Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Updating DateTime From Router/Gateway on statrup

DateTim.Now Clock Startup Router DD-WRT Gateway

  • Please log in to reply
1 reply to this topic

#1 tridy

tridy

    Advanced Member

  • Members
  • PipPipPip
  • 68 posts
  • LocationStockholm, Sweden

Posted 17 June 2015 - 11:04 PM

As soon as I got my SD cards, I realized that it's nice to have files with the created date that is actually Now, hopefully matching the actual time quite closely over the time that Netduino has a single session.

 

Solution on the other posts like this show using time servers and fetching the internet time from them. I realized that most of the time there is a router (in my case this is one with DD-WRT firmare) in between the time server and Netduino that should be perfectly aware of the current time. In addition, you might not want or there might be no access to the Internet, just the Intranet. I assumes that the gateway will give some sort of response to http request on port 80, being some info page (in case of DD-WRT firmare) or login page for configuration or "no access" but the reply should return the header with the correct date all the time. In addition, most of the routers are able to sync with Internet time on its own so it should give good values. So, here is the solution that works for my setup/environment:

 

Steps:

 

  1. waiting for the IP address to be assigned to a network interface
  2. getting gateway address from network interface
  3. sending the http request to the gateway
  4. read just the "Date" Header of the response (not the whole response) that is in standard HTTP GMT format
  5. parse the "Date" Header string into date.
  6. assign the value to the system time via Utility

 

One variable that is required from the user is the GMT Offset.

 

So, it could be used something like this:

public static void Main()
{
    DateTimeEx.FromGmtOffset(2).InitializeSystemClock();
    Debug.Print("Local time: " + DateTime.Now);
}

and the actual implementation:

    public sealed class DateTimeEx
    {
        private int _gmtOffset = 0;

        public static string[] Months = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

        private DateTimeEx() {}

        public static DateTimeEx FromGmtOffset(int gmtHoursOffset)
        {
            return new DateTimeEx
            {
                _gmtOffset = gmtHoursOffset
            };
        }

        public void InitializeSystemClock()
        {
            WaitForDhcp();
            var dateTimeNow = GetGmtNowFromGateway();
            Utility.SetLocalTime(dateTimeNow.AddHours(_gmtOffset));
        }

        private void WaitForDhcp()
        {
            while (IPAddress.GetDefaultLocalAddress() == IPAddress.Any) ;
        }

        private DateTime GetGmtNowFromGateway()
        {
            var interfaces = NetworkInterface.GetAllNetworkInterfaces();
            NetworkInterface firstInterface = interfaces[0];
            
            if (firstInterface.IPAddress == IPAddress.Any.ToString())
            {
                return DateTime.Now;
            }

            string gateway = firstInterface.GatewayAddress;
            return GetGatewayDateTime(gateway);
        }

        private DateTime GetGatewayDateTime(string routerAddress)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(@"http://" + routerAddress + @"/");
            request.Method = "GET";

            string dateHeader;

            using(var response = request.GetResponse())
            {
                dateHeader = response.Headers["Date"];
            }

            return ParseDate(dateHeader);
        }

        private DateTime ParseDate(string dateHeader)
        {
            var values = dateHeader.Split(' ', ':');
            int day = int.Parse(values[1]);
            int month = GetMonthId(values[2]);
            int year = int.Parse(values[3]);
            int hour = int.Parse(values[4]);
            int minute = int.Parse(values[5]);
            int second = int.Parse(values[6]);

            return new DateTime(year, month, day, hour, minute, second);
        }

        private int GetMonthId(string month)
        {
            for (int i = 0; i < Months.Length; i++)
            {
                if (Months[i] == month)
                {
                    return i + 1;
                }
            }

            throw new ArgumentOutOfRangeException("Could not find corresponding month with code " + month);
        }
    }

so, now the created files will be of the correct Created date and DateTime.Now will give the correct value. And of course it is possible to get the time from the router without updating the system time on Netduino.



#2 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 18 June 2015 - 01:07 AM

Cool. Thanks for sharing this with us, Tridy!





Also tagged with one or more of these keywords: DateTim.Now, Clock, Startup, Router, DD-WRT, Gateway

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.