Main Site Documentation

Auto daylight savings problem with COBRA and NTP synchro


#1

Hi,

I’m rewriting the NTP synchronisation code for the COBRA. Most existing codes do not use the latest NETMF version or cannot compile correctly.

The code I have works almost fine. It gets the time from the NTP server. I manually put the time zone shift in the SetTimeZoneOffset variable.

The problem I have is that despite the set of the AutoDayLightSavings to true, the board does not apply the shift of 1 hour for dayligth savings. There is probably a variable somewhere to set that I am within a country applying daylight savings (France actually) but I can’t find how to do that.

Can someone help ?

Thanks,

Stephan.

Here is my code :



            #region Get an IP address from the DHCP Server
            #endregion

            TimeServiceSettings NTPTime = new TimeServiceSettings();
            NTPTime.AutoDayLightSavings = true;
            NTPTime.ForceSyncAtWakeUp = true;
            NTPTime.RefreshTime = 3600;
            NTPTime.PrimaryServer = Dns.GetHostEntry("fr.pool.ntp.org").AddressList[0].GetAddressBytes();
            TimeService.Settings = NTPTime;
            TimeService.SetTimeZoneOffset(60); // France Time zone : GMT+1
            TimeService.Start();

            while (true)
            {
                Debug.Print("It is : " + DateTime.Now.ToString());
                Thread.Sleep(1000);
            }


#2

So, in summer time, your Cobra is still in winter time (or reverse)?

How about this:

TimeServiceSettings.AutoDayLightSavings; Indicates whether the system time is automatically updated for daylight savings.
I asume, reading your code, this setting is correct.

Have you checked you get any errors?

[italic]Public Events[/italic]
TimeService.SystemTimeChanged; Occurs when the system time changed.
TimeService.TimeSyncFailed; Occurs when time sync fails.


#3

Hi Colin,

I did check and run the code without error, but resulting in a time difference matching the daylight savings shift. What I suspect is that, even if one sets the AutodayLightSavings at true, it doesn’t mean that the daylight savings is applied because it depends on the country you leave in, rigtht ?

If that assumption is true, then I don’t know where to set the country in order to decide whether this is a country where daylight savings applies or not.

Stephan.


#4

I doubt netmf goes that far. Maybe take a look at the netmf core source code in the porting kit to see how it works.


#5

StephW,

How about forcing the update?

TimeService.UpdateNow();

#6

Another thing i just came up:

Maybe at start-up, the TimeServiceSettings object is null and just setting the PrimaryServer property results in null as well.
Once a proper instance of TimerServiceSettings is added to the TimerService it does work?

It’s just a guess… let me know.


#7

I think the Timezone manager via XML contributed code http://code.tinyclr.com/project/274/timezone-management-via-xml/ handles DST change


#8

Class is looking good Brett. Looks very promising for Stephan


#9

it’s not mine, but yeah it’s a great contribution !


#10

I know :wink: I only thanked you for the post :stuck_out_tongue:


#11

Hi Guys,

I did my homework. Daylight savings is (indeed) not implemented in NETMF. Here is what I found : The NTP servers give only one time : the universal time at GMT. There is no notion of TimeZone nor Daylight Savings. You have to implement it in your code.

Implementing TimeZone is easy. One variable containing the number of minutes to add to GMT, and that’s it.

For Daylight Savings, it’s a little bit trickier, because it depends on the country you leave in (that’s why you are been asked about a town or a country when you install an operating system)

So I implemented a short class that synchronize the COBRA clock with NTP servers, applying TimeZone and Daylight savings for European Countries. Outside Europe, you may need to modify the code to apply the daylight savings according to your country.

Using the class is VERY simple, you just need to instanciate an object of the class and that’s it. I used event handlers, so each time the synchronisation with NTP servers is done, there is a check for Daylight savings, so , you automatically switch between summer and winter time.

I need to add a piece of code to save the current date and time in static memory, in case there is a reboot and the Cobra cannot reconnect to Internet.

Here is the class, followed by and example of how to use it :


using System;
using System.Net;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Time;

    class NTPService
    {
        private static int localTimeZone = 60;                  // Time shift for Paris - Change according to your location
        private static int daylightSavingsShift = 0;            // Should be 60 in summer time, 0 during winter
        private string primaryNTPServer = "fr.pool.ntp.org";    // Primary NTP server, put the nearest from your location
        private string secondaryNTPServer = "pool.ntp.org";     // Alternate NTP server, choose the most generic one
        private TimeServiceSettings NTPTime;                    // NTP Client configuration

        public NTPService() // Initialize and start the NTP synchronization
        {
            // Initialize the NTP parameters

            NTPTime = new TimeServiceSettings();    // Initialize the configuration structure
            NTPTime.AutoDayLightSavings = true;     // That does nothing on NETMF, indeed
            NTPTime.ForceSyncAtWakeUp = true;       // Not sure that works
            NTPTime.RefreshTime = 7200;               // Refresh rate un second, here 2 hours (7200), put 60 for testing purpose
            
            // Get the IP addresses from the NTP servers using DNS requests

            try
            {
                NTPTime.PrimaryServer = Dns.GetHostEntry(primaryNTPServer).AddressList[0].GetAddressBytes();
                NTPTime.AlternateServer = Dns.GetHostEntry(secondaryNTPServer).AddressList[0].GetAddressBytes();
            }
            catch (Exception e)
            {
                Debug.Print("NTPService : Exception on DNS lookup for NTP servers address");
                Debug.Print(e.Message);
            }

            // Assign the Event handlers to manage the updates and starts the service

            TimeService.Settings = NTPTime;
            TimeService.SystemTimeChanged += new SystemTimeChangedEventHandler(onSystemTimeChanged);
            TimeService.TimeSyncFailed += new TimeSyncFailedEventHandler(onTimeSyncFailed);
            TimeService.Start();
        }

        static void onSystemTimeChanged(Object sender, SystemTimeChangedEventArgs e) // Called on successful NTP Synchronisation
        {
            DateTime now = DateTime.Now; // Used to manipulate dates and time

            #region Check is we are in summer time and thus daylight savings apply

            // Check if we are in Daylight savings. The following algorythm works pour Europe and associated countries
            // In Europe, daylight savings (+60 min) starts the last sunday of march and ends the last sunday of october

            DateTime aprilFirst = new DateTime(now.Year, 4, 1);
            DateTime novemberFirst = new DateTime(now.Year, 11, 1);
            int[] sundayshift = new int[] { 0, -1, -2, -3, -4, -5, -6 };
            int marchLastSunday = aprilFirst.DayOfYear + sundayshift[(int)aprilFirst.DayOfWeek];
            int octoberLastSunday = novemberFirst.DayOfYear + sundayshift[(int)novemberFirst.DayOfWeek];

            if ((now.DayOfYear >= marchLastSunday) && (now.DayOfYear < octoberLastSunday))
                daylightSavingsShift = 60;
            else
                daylightSavingsShift = 0;

            TimeService.SetTimeZoneOffset(localTimeZone + daylightSavingsShift);

            #endregion

            // Display the synchronized date on the Debug Console

            now = DateTime.Now;
            string date = now.ToString("dd/MM/yyyy");
            string heure = now.ToString("HH:mm:ss");
            Debug.Print(date + " // " + heure);
        }

        static void onTimeSyncFailed(Object sender, TimeSyncFailedEventArgs e) // Called on unsuccessful NTP Synchronisation
        {
            Debug.Print("NTPService : Error synchronizing system time with NTP server");
        }    
    
    }

How to use the class :


namespace EMXTest
{
    public class Program
    {
        public static void Main()
        {
            NTPService timeSynchro;

            #region Get an IP address from the DHCP Server

            Microsoft.SPOT.Net.NetworkInformation.NetworkInterface NI = Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0];

            if (NI.IsDhcpEnabled == false)
            {
                Debug.Print("Enabling DHCP.");
                NI.EnableDhcp();
                Debug.Print("DCHP - IP Address = " + NI.IPAddress + " ... Net Mask = " + NI.SubnetMask + " ... Gateway = " + NI.GatewayAddress);
            }
            else
            {
                Debug.Print("Renewing DHCP lease.");
                NI.RenewDhcpLease();
                Debug.Print("DCHP - IP Address = " + NI.IPAddress + " ... Net Mask = " + NI.SubnetMask + " ... Gateway = " + NI.GatewayAddress);
            }

            #endregion
            
            timeSynchro = new NTPService();

            while (true)
            {
                Debug.Print("I'm Here");
                Thread.Sleep(10000);
            }
        }
    }
}

Enjoy.

Stephan.


#12

I used the existing DaylightTime class for that. See my implementation here: http://code.tinyclr.com/project/242/calculate-sunset-and-sunrise-time/