Exemplo n.º 1
0
        private static void Main(string[] args)
        {
            if (args.Length != 1)
            {
                Console.WriteLine("Usage: led-matrix-weather <openweathermap.org API key>");
                Console.WriteLine();
                Console.WriteLine("If wrong key is used or there is no network connection");
                Console.WriteLine("example data will be displayed.");
                Console.WriteLine();
                Console.WriteLine("For the first 30 seconds of execution");
                Console.WriteLine("IP addresses will be displayed instead of data.");
                return;
            }

            s_client = new Weather(args[0]);

            UpdateWeather();
            Task.Run(WeatherUpdater);
            Task.Run(IpsGetter);

            PinMapping   mapping = PinMapping.MatrixBonnetMapping32;
            RGBLedMatrix matrix  = new RGBLedMatrix(mapping, 64, 64, 2, 2);

            Task drawing = Task.Run(() =>
            {
                matrix.StartRendering();

                while (s_scenario is object)
                {
                    Action <RGBLedMatrix> scenario = s_scenario;

                    Stopwatch sw = Stopwatch.StartNew();
                    scenario(matrix);

                    if (sw.ElapsedMilliseconds < 100)
                    {
                        Debug.WriteLine("Scenario execution finished in less than 100ms. This is likely due to bug.");
                    }
                }
            });

            try
            {
                if (!Console.IsOutputRedirected)
                {
                    while (s_scenario is object && Console.ReadKey(intercept: true).Key != ConsoleKey.Q)
                    {
                        Thread.Sleep(10);
                    }

                    s_scenario = null;
                }

                drawing.Wait();
            }
            finally
            {
                matrix.Dispose();
            }
        }
Exemplo n.º 2
0
        static unsafe void Demo1(RGBLedMatrix matrix)
        {
            play = true;

            try
            {
                BdfFont font  = BdfFont.Load(@"fonts/10x20.bdf");
                BdfFont font1 = BdfFont.Load(@"fonts/8x13B.bdf");
                matrix.Fill(0, 0, 0);
                Thread.Sleep(100);

                int    x             = matrix.Width - 1;
                string text          = "Hello .NET IoT";
                int    fullTextWidth = text.Length * font.Width;

                while (play)
                {
                    matrix.DrawText(x, 0, text, font, 0, 0, 255, 0, 0, 0);
                    x--;
                    if (x == -fullTextWidth)
                    {
                        x = matrix.Width - 1;
                    }

                    string d = DateTime.Now.ToString("hh:mm:ss");
                    matrix.DrawText(0, font.Height + 1, d, font1, 128, 128, 0, 0, 0, 0);

                    Thread.Sleep(25);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
Exemplo n.º 3
0
        static void Demo8(RGBLedMatrix matrix)
        {
            play = true;

            try
            {
                var sw = Stopwatch.StartNew();
                while (play)
                {
                    float time = sw.ElapsedMilliseconds / 1000f;
                    for (int ix = 0; ix < matrix.Width; ix++)
                    {
                        for (int iy = 0; iy < matrix.Height; iy++)
                        {
                            Vector2 uv = new Vector2(ix / (float)(matrix.Width - 1), iy / (float)(matrix.Height - 1));
                            Vector3 cv = Star(uv, time);
                            Color   c  = ToSRGB(cv.X, cv.Y, cv.Z);
                            matrix.SetPixel(ix, iy, c.R, c.G, c.B);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
        static int Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("font-example.exe [font_path] <text>");
                return(-1);
            }
            string text = "Hello World!";

            if (args.Length > 1)
            {
                text = args[1];
            }


            var matrix = new RGBLedMatrix(32, 2, 1);
            var canvas = matrix.CreateOffscreenCanvas();
            var font   = new RGBLedFont(args[0]);

            canvas.DrawText(font, 1, 6, new Color(0, 255, 0), text);
            matrix.SwapOnVsync(canvas);

            while (!Console.KeyAvailable)
            {
                Thread.Sleep(250);
            }

            return(0);
        }
Exemplo n.º 5
0
        static void Demo2(RGBLedMatrix matrix)
        {
            int length = matrix.Width / 4;
            int height = matrix.Height / 4;

            play = true;
            while (play)
            {
                matrix.FillRectangle(0, 0, length, length, 255, 0, 0);
                matrix.FillRectangle(length, 0, length, length, 0, 255, 0);
                matrix.FillRectangle(2 * length, 0, length, length, 0, 0, 255);
                matrix.FillRectangle(3 * length, 0, length, length, 255, 255, 0);

                matrix.FillRectangle(0, height, length, length, 255, 0, 255);
                matrix.FillRectangle(length, height, length, length, 255, 255, 255);
                matrix.FillRectangle(2 * length, height, length, length, 0, 130, 0);
                matrix.FillRectangle(3 * length, height, length, length, 130, 0, 0);

                matrix.FillRectangle(0, 2 * height, length, length, 0, 0, 128);
                matrix.FillRectangle(length, 2 * height, length, length, 192, 192, 192);
                matrix.FillRectangle(2 * length, 2 * height, length, length, 128, 128, 0);
                matrix.FillRectangle(3 * length, 2 * height, length, length, 128, 128, 128);

                matrix.FillRectangle(0, 3 * height, length, length, 40, 40, 40);
                matrix.FillRectangle(length, 3 * height, length, length, 80, 80, 80);
                matrix.FillRectangle(2 * length, 3 * height, length, length, 120, 120, 120);
                matrix.FillRectangle(3 * length, 3 * height, length, length, 0, 120, 120);

                Thread.Sleep(5000);
            }
        }
Exemplo n.º 6
0
        static unsafe void Demo4(RGBLedMatrix matrix)
        {
            play = true;

            byte blue = 0x15;

            matrix.Fill(0, 0, blue);

            using (WebClient client = new WebClient())
            {
                int    lastMinute  = -1;
                string temperature = "";

                BdfFont font  = BdfFont.Load(@"fonts/6x12.bdf");
                BdfFont font1 = BdfFont.Load(@"fonts/5x7.bdf");

                Bitmap weatherIcon = null;
                string lastIcon    = null;
                string description = "";

                while (play)
                {
                    DateTime time = DateTime.Now;
                    if (Math.Abs(time.Minute - lastMinute) > 4)
                    {
                        lastMinute = time.Minute;
                        string xml = client.DownloadString("http://api.openweathermap.org/data/2.5/weather?q=Redmond,US&mode=xml&units=imperial&APPID=" + s_weatherKey);

                        XDocument doc     = XDocument.Parse(xml);
                        XElement  element = doc.Root.Element("temperature");
                        temperature = ((int)Math.Round(Double.Parse(element.Attribute("value").Value))).ToString(CultureInfo.InvariantCulture);

                        element = doc.Root.Element("weather");
                        string icon = element.Attribute("icon").Value;
                        description = element.Attribute("value").Value;

                        if (lastIcon != icon)
                        {
                            weatherIcon = new Bitmap("bitmaps/" + icon + ".bmp");
                        }

                        matrix.DrawBitmap(20, 2, weatherIcon, 255, 255, 255, 0, 0, blue);
                        matrix.DrawText(Math.Max(0, matrix.Width - description.Length * font1.Width), 42, description, font1, 128, 128, 128, 0, 0, blue);
                        matrix.DrawText(2, 2 + font.Height, temperature + "\u00B0", font, 128, 128, 128, 0, 0, blue);
                    }

                    matrix.DrawText(2, 2, time.ToString("ddd"), font, 128, 128, 128, 0, 0, blue);
                    matrix.DrawText(2, matrix.Height - font.Height, time.ToString("hh:mm:sstt"), font, 128, 128, 128, 0, 0, blue);

                    Thread.Sleep(200);
                }
            }
        }
        static int Main(string[] args)
        {
            var matrix = new RGBLedMatrix(new RGBLedMatrixOptions {
                Rows = 32, Cols = 64
            });
            var       canvas        = matrix.CreateOffscreenCanvas();
            var       maxBrightness = matrix.Brightness;
            var       count         = 0;
            const int c             = 255;

            while (!Console.KeyAvailable)
            {
                if (matrix.Brightness < 1)
                {
                    matrix.Brightness = maxBrightness;
                    count            += 1;
                }
                else
                {
                    matrix.Brightness -= 1;
                }

                switch (count % 4)
                {
                case 0:
                    canvas.Fill(new Color(c, 0, 0));
                    break;

                case 1:
                    canvas.Fill(new Color(0, c, 0));
                    break;

                case 2:
                    canvas.Fill(new Color(0, 0, c));
                    break;

                case 3:
                    canvas.Fill(new Color(c, c, c));
                    break;
                }

                canvas = matrix.SwapOnVsync(canvas);

                Thread.Sleep(20);
            }

            return(0);
        }
Exemplo n.º 8
0
        static int Main(string[] args)
        {
            Console.WriteLine("Program started");
            //while (true)
            //{
            //    Console.WriteLine("waiting for debugger to attach...");
            //    if (Debugger.IsAttached) break;
            //    System.Threading.Thread.Sleep(1000);
            //}

            var options = new RGBLedMatrixOptions
            {
                Rows         = 64,
                Cols         = 64,
                GpioSlowdown = 4,
                Brightness   = 100,
                ChainLength  = 1
            };

            Console.WriteLine("Starting to initialize Matrix");
            var matrix = new RGBLedMatrix(options);
            var canvas = matrix.CreateOffscreenCanvas();

            Console.WriteLine("Starting Visualization");

            for (var i = 0; i < 1000; ++i)
            {
                canvas.Fill(new Color(100, 100, 100));
                for (var y = 0; y < canvas.Height; ++y)
                {
                    for (var x = 0; x < canvas.Width; ++x)
                    {
                        canvas.SetPixel(x, y, new Color(i & 0xff, x, y));
                    }
                }
                canvas.DrawCircle(canvas.Width / 2, canvas.Height / 2, 6, new Color(0, 0, 255));
                canvas.DrawLine(canvas.Width / 2 - 3, canvas.Height / 2 - 3, canvas.Width / 2 + 3, canvas.Height / 2 + 3, new Color(0, 0, 255));
                canvas.DrawLine(canvas.Width / 2 - 3, canvas.Height / 2 + 3, canvas.Width / 2 + 3, canvas.Height / 2 - 3, new Color(0, 0, 255));

                canvas = matrix.SwapOnVsync(canvas);
            }

            Console.WriteLine("Done.");
            Console.ReadKey();
            return(0);
        }
Exemplo n.º 9
0
        static unsafe void Demo6(RGBLedMatrix matrix)
        {
            play = true;

            try
            {
                matrix.Fill(0, 0, 0);

                Bitmap [] bitmaps = new Bitmap []
                {
                    new Bitmap(@"bitmaps/dotnet-bot-branded-32x32.bmp"),
                    new Bitmap(@"bitmaps/i-love-dotnet.bmp")
                };

                int x           = matrix.Width - 1;
                int bitmapIndex = 0;
                while (play)
                {
                    matrix.DrawBitmap(x, 0, bitmaps[bitmapIndex]);

                    if (x + bitmaps[bitmapIndex].Width < matrix.Width)
                    {
                        matrix.FillRectangle(x + bitmaps[bitmapIndex].Width, 0, matrix.Width - x - bitmaps[bitmapIndex].Width, matrix.Height, 0, 0, 0);
                    }

                    x--;

                    if (x == -bitmaps[bitmapIndex].Width)
                    {
                        bitmapIndex = (bitmapIndex + 1) % bitmaps.Length;
                        x           = matrix.Width - 1;
                    }

                    Thread.Sleep(25);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
Exemplo n.º 10
0
        public Renderer(bool noRender = false)
        {
            this.NoRender = noRender;
            RGBLedMatrixOptions ledMatrixOptions = new RGBLedMatrixOptions();

            ledMatrixOptions.Cols         = 32;
            ledMatrixOptions.Rows         = 32;
            ledMatrixOptions.GpioSlowdown = 2;

            if (!NoRender)
            {
                matrix = new RGBLedMatrix(ledMatrixOptions);
                canvas = matrix.CreateOffscreenCanvas();
                Console.WriteLine("Matrix and Canvas initalized");
            }

            updateTimer.Elapsed += new ElapsedEventHandler(_OnUpdate);
            updateTimer.Interval = 16;

            _thread = new Thread(new ThreadStart(Render));
        }
Exemplo n.º 11
0
        static unsafe void Demo7(RGBLedMatrix matrix)
        {
            play = true;

            try
            {
                matrix.Fill(0, 0, 0);

                while (play)
                {
                    matrix.SetPixel(matrix.Width / 2, matrix.Height / 2, 255, 0, 0);
                    matrix.DrawCircle(matrix.Width / 2, matrix.Height / 2, 14, 255, 0, 0);
                    matrix.DrawCircle(matrix.Width / 2, matrix.Height / 2, 9, 0, 255, 0);
                    matrix.DrawCircle(matrix.Width / 2, matrix.Height / 2, 6, 0, 0, 255);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
Exemplo n.º 12
0
        private static void ScrollText(
            RGBLedMatrix matrix,
            string text,
            BdfFont font,
            int startPos,
            int endPos,
            byte red, byte green, byte blue, byte bkRed, byte bkGreen, byte bkBlue)
        {
            if (startPos < endPos)
            {
                return;
            }

            text = text + " "; // to clear the text when scrolling
            int fullTextWidth = text.Length * font.Width;

            while (startPos >= endPos)
            {
                matrix.DrawText(startPos, 0, text, font, red, green, blue, bkRed, bkGreen, bkBlue);
                startPos--;
                Thread.Sleep(20);
            }
        }
Exemplo n.º 13
0
        static int Main(string[] args)
        {
            var matrix = new RGBLedMatrix(32, 2, 1);
            var canvas = matrix.CreateOffscreenCanvas();

            for (var i = 0; i < 1000; ++i)
            {
                for (var y = 0; y < canvas.Height; ++y)
                {
                    for (var x = 0; x < canvas.Width; ++x)
                    {
                        canvas.SetPixel(x, y, new Color(i & 0xff, x, y));
                    }
                }
                canvas.DrawCircle(canvas.Width / 2, canvas.Height / 2, 6, new Color(255, 0, 255));
                canvas.DrawLine(canvas.Width / 2 - 3, canvas.Height / 2 - 3, canvas.Width / 2 + 3, canvas.Height / 2 + 3, new Color(0, 0, 255));
                canvas.DrawLine(canvas.Width / 2 - 3, canvas.Height / 2 + 3, canvas.Width / 2 + 3, canvas.Height / 2 - 3, new Color(0, 0, 255));

                canvas = matrix.SwapOnVsync(canvas);
            }

            return(0);
        }
Exemplo n.º 14
0
        static int Main(string[] args)
        {
            var matrix = new RGBLedMatrix(new RGBLedMatrixOptions {
                ChainLength = 2
            });
            var canvas    = matrix.CreateOffscreenCanvas();
            var rnd       = new Random();
            var points    = new List <Point>();
            var recycled  = new Stack <Point>();
            int frame     = 0;
            var stopwatch = new Stopwatch();

            while (!Console.KeyAvailable)
            {
                stopwatch.Restart();

                frame++;

                if (frame % FRAME_STEP == 0)
                {
                    if (recycled.Count == 0)
                    {
                        points.Add(new Point(rnd.Next(0, canvas.Width - 1), 0));
                    }
                    else
                    {
                        var point = recycled.Pop();
                        point.x        = rnd.Next(0, canvas.Width - 1);
                        point.y        = 0;
                        point.recycled = false;
                    }
                }

                canvas.Clear();

                foreach (var point in points)
                {
                    if (!point.recycled)
                    {
                        point.y++;

                        if (point.y - MAX_HEIGHT > canvas.Height)
                        {
                            point.recycled = true;
                            recycled.Push(point);
                        }

                        for (var i = 0; i < MAX_HEIGHT; i++)
                        {
                            canvas.SetPixel(point.x, point.y - i, new Color(0, 255 - i * COLOR_STEP, 0));
                        }
                    }
                }

                canvas = matrix.SwapOnVsync(canvas);

                // force 30 FPS
                var elapsed = stopwatch.ElapsedMilliseconds;
                if (elapsed < 33)
                {
                    Thread.Sleep(33 - (int)elapsed);
                }
            }

            return(0);
        }
Exemplo n.º 15
0
        static int Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("font-example.exe [font_path] <text>");
                return(-1);
            }
            string text      = "abcdefghijklmnopqrstuvwxyz";
            string text_high = "AAPL 123.45";
            string text_low  = "@ 12.4%";

            var matrix = new RGBLedMatrix(16, 0, 0);
            var canvas = matrix.CreateOffscreenCanvas();
            var font   = new RGBLedFont(args[0]);

            var x     = -40;
            var top_y = 8;
            var bot_y = 16;

            for (var j = 0; j < 1000; j++)
            {
                for (var i = 0; i < 80; i++)
                {
                    x = x + 1;

                    // set all matrix low
                    canvas.Clear();

                    // draw the top line
                    canvas.DrawText(font, x, top_y, new Color(0, 255, 0), text_high);
                    canvas.DrawText(font, x, bot_y, new Color(0, 255, 0), text_low);

                    matrix.SwapOnVsync(canvas);

                    Thread.Sleep(100);


                    //while (!Console.KeyAvailable)
                    //{
                    //    Thread.Sleep(1000);
                    //}
                }
                x     = -40;
                top_y = 8;
                bot_y = 16;
            }

            /*
             * // row test
             * for(var i = 0; i < 1000; i++){
             *  canvas.Clear();
             *
             *  canvas.DrawText(font, x, i, new Color(0, 255, 0), text);
             *
             *  matrix.SwapOnVsync(canvas);
             *
             *  Thread.Sleep(100);
             * }
             */

            return(0);
        }
Exemplo n.º 16
0
        private static void WeatherDemo(RGBLedMatrix matrix)
        {
            BdfFont font  = BdfFont.Load(@"fonts/10x20.bdf");
            BdfFont font1 = BdfFont.Load(@"fonts/8x13B.bdf");

            matrix.Fill(0, 0, 0);
            Thread.Sleep(100);

            int textLeft = 0;

            const int feedUpdateMs   = 500;
            const int drawIntervalMs = 25;
            const int iterations     = feedUpdateMs / drawIntervalMs;

            byte Col(float x)
            {
                return((byte)Math.Clamp(x * 255, 0, 255));
            }

            string text          = string.Empty;
            int    fullTextWidth = 0;

            Stopwatch sw = Stopwatch.StartNew();

            while (s_scenario != null)
            {
                text          = " * " + string.Join(" * ", WeatherFeed());
                fullTextWidth = text.Length * font.Width;

                for (int i = 0; i < iterations && s_scenario != null; i++, textLeft--)
                {
                    matrix.DrawText(textLeft, -2, text, font, 0, 0, 255, 0, 0, 0);

                    if (textLeft + fullTextWidth < matrix.Width)
                    {
                        matrix.DrawText(textLeft + fullTextWidth, -2, text, font, 0, 0, 255, 0, 0, 0);
                    }

                    if (textLeft + fullTextWidth <= 0)
                    {
                        textLeft += fullTextWidth;
                    }

                    DateTimeOffset localNow = DateTimeOffset.Now;
                    DateTimeOffset pstNow   = TimeZoneInfo.ConvertTime(localNow, s_timeZonePst);
                    string         d        = pstNow.ToString("hh:mm:ss");
                    matrix.DrawText(0, font.Height + 1 - 2, d, font1, 0, 255, 0, 0, 0, 0);

                    int   halfHeight = matrix.Height / 2;
                    int   halfWidth  = matrix.Width / 2;
                    float time       = sw.ElapsedMilliseconds / 1000f;
                    for (int x = 0; x < matrix.Width; x++)
                    {
                        if (x < halfWidth)
                        {
                            for (int y = halfHeight; y < matrix.Height; y++)
                            {
                                Vector3 col3  = Clock(new Vector2((float)x / halfWidth, (float)(y - halfHeight) / halfHeight), pstNow);
                                Color   color = Color.FromArgb(Col(col3.X), Col(col3.Y), Col(col3.Z));
                                matrix.SetPixel(x, y, color.R, color.G, color.B);
                            }
                        }
                        else
                        {
                            for (int y = halfHeight; y < matrix.Height; y++)
                            {
                                Vector2 uv    = new Vector2((float)(x - halfWidth) / halfWidth, (float)(y - halfHeight) / halfHeight);
                                Vector3 col3  = OpenWeatherIcon(uv, s_weatherResponse.Weather[0].Icon, time);
                                Color   color = Color.FromArgb(Col(col3.X), Col(col3.Y), Col(col3.Z));
                                matrix.SetPixel(x, y, color.R, color.G, color.B);
                            }
                        }
                    }

                    Thread.Sleep(drawIntervalMs);
                }
            }
        }
Exemplo n.º 17
0
        private static void Main(string[] args)
        {
            Console.WriteLine($"Hello Matrix World!");

            // If using 64x64 with Bonnet (https://www.adafruit.com/product/3211), you can just do
            // PinMapping mapping = PinMapping.MatrixBonnetMapping64;

            // If using 32x32 with Bonnet (https://www.adafruit.com/product/3211), you can just do
            PinMapping mapping = PinMapping.MatrixBonnetMapping32;

            // If not using Bonnet, will need to provide the manual GPIO mapping using PinMapping

            // To create RGBLedMatrix for 32x32 panel, do the following
            RGBLedMatrix matrix = new RGBLedMatrix(mapping, 32, 32);

            // To create RGBLedMatrix for 64x64 panel, do the following
            // RGBLedMatrix matrix = new RGBLedMatrix(mapping, 64, 64);

            // PinMapping mapping = PinMapping.MatrixBonnetMapping64;
            // RGBLedMatrix matrix = new RGBLedMatrix(mapping, 64, 64);

            // If you chain 4 32x32 panels serially, you can do
            // RGBLedMatrix matrix = new RGBLedMatrix(mapping, 128, 32);

            // If you chain 4 32x32 panels having 2 rows chaining (2 panels in first row an d2 panels in second row).
            // RGBLedMatrix matrix = new RGBLedMatrix(mapping, 64, 64, 2, 2);

            Task.Run(() =>
            {
                matrix.StartRendering();

                while (scenario != 0)
                {
                    switch (scenario)
                    {
                    case 1: Demo1(matrix); break;

                    case 2: Demo2(matrix); break;

                    case 3: Demo3(matrix); break;

                    case 4: Demo4(matrix); break;

                    case 5: Demo5(matrix); break;

                    case 6: Demo6(matrix); break;

                    case 7: Demo7(matrix); break;

                    case 8: Demo8(matrix); break;

                    default:
                        scenario = 2;
                        break;
                    }
                }
            });

            ConsoleKeyInfo cki;

            Console.WriteLine($"Press q to exit.");
            System.Interop.ThreadHelper.SetCurrentThreadHighPriority();

            do
            {
                cki = Console.ReadKey();

                if (cki.KeyChar == '+')
                {
                    matrix.PWMDuration = matrix.PWMDuration + 100;
                    Console.WriteLine($"     ({matrix.PWMDuration})");
                }

                if (cki.KeyChar == '-')
                {
                    matrix.PWMDuration = matrix.PWMDuration - 100;
                    Console.WriteLine($"     ({matrix.PWMDuration})");
                }

                if (cki.KeyChar == 'f')
                {
                    Console.WriteLine($"Frame Time: {matrix.FrameTime} \u00B5s");
                    Console.WriteLine($"Duration : { matrix.PWMDuration }");
                }

                if (cki.KeyChar >= '1' && cki.KeyChar <= '9')
                {
                    play     = false;
                    scenario = cki.KeyChar - '0';
                    Thread.Sleep(1000);
                }
            } while (cki.KeyChar != 'q');

            play     = false;
            scenario = 0;
            Thread.Sleep(1000);
            matrix.Dispose();
        }
Exemplo n.º 18
0
        static void Demo3(RGBLedMatrix matrix)
        {
            try
            {
                play = true;

                byte blue = 0x10;
                matrix.Fill(0, 0, blue);

                TimeZoneInfo [] zones       = new TimeZoneInfo [s_citiesData.Length];
                string []       weatherUrls = new string [s_citiesData.Length];
                for (int i = 0; i < s_citiesData.Length; i++)
                {
                    weatherUrls[i] = String.Format("http://api.openweathermap.org/data/2.5/weather?q={0},{1}&mode=xml&units=imperial&APPID={2}", s_citiesData[i].City, s_citiesData[i].CountryCode, s_weatherKey);
                    zones[i]       = TimeZoneInfo.FindSystemTimeZoneById(s_citiesData[i].ZoneId);
                }

                using (WebClient client = new WebClient())
                {
                    BdfFont font  = BdfFont.Load(@"fonts/6x12.bdf");
                    BdfFont font1 = BdfFont.Load(@"fonts/5x7.bdf");
                    BdfFont font2 = BdfFont.Load(@"fonts/4x6.bdf");

                    int cityIndex = 0;

                    while (play)
                    {
                        string    xml         = client.DownloadString(weatherUrls[cityIndex]);
                        XDocument doc         = XDocument.Parse(xml);
                        XElement  element     = doc.Root.Element("temperature");
                        string    temperature = ((int)Math.Round(Double.Parse(element.Attribute("value").Value))).ToString(CultureInfo.InvariantCulture);

                        element = doc.Root.Element("weather");
                        string description = element.Attribute("value").Value + "                                           ";

                        element = doc.Root.Element("humidity");
                        string humidity = element.Attribute("value").Value + element.Attribute("unit").Value + "             ";
                        element = doc.Root.Element("city").Element("sun");
                        string sunRise = TimeZoneInfo.ConvertTimeFromUtc(DateTime.Parse(element.Attribute("rise").Value, CultureInfo.InvariantCulture), zones[cityIndex]).ToString("hh:mm tt");
                        string sunSet  = TimeZoneInfo.ConvertTimeFromUtc(DateTime.Parse(element.Attribute("set").Value, CultureInfo.InvariantCulture), zones[cityIndex]).ToString("hh:mm tt");

                        int pos = Math.Max(0, (matrix.Width - (s_citiesData[cityIndex].City.Length * font.Width))) / 2;
                        ScrollText(
                            matrix,
                            s_citiesData[cityIndex].City,
                            font,
                            matrix.Width - 1,
                            pos,
                            128, 128, 128, 0, 0, blue);

                        int y = font.Height;
                        matrix.DrawText((matrix.Width - (temperature.Length + 1) * font1.Width) / 2, y, temperature + "\u00B0", font1, 255, 255, 0, 0, 0, blue);

                        y += font1.Height + 2;
                        matrix.DrawText(2, y, description, font2, 128, 128, 128, 0, 0, blue);

                        y += font2.Height + 2;
                        matrix.DrawText(2, y, "humidity: ", font2, 128, 128, 128, 0, 0, blue);
                        matrix.DrawText(font2.Width * "humidity: ".Length + 2, y, humidity, font2, 255, 255, 0, 0, 0, blue);

                        y += font2.Height;
                        string localTime = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, zones[cityIndex]).ToString("hh:mm tt");
                        matrix.DrawText((matrix.Width - localTime.Length * font.Width) / 2, y, localTime, font, 255, 255, 0, 0, 0, blue);

                        y += font.Height + 2;
                        matrix.DrawText(2, y, "Sun Rise: ", font2, 128, 128, 128, 0, 0, blue);
                        matrix.DrawText(2 + "Sun Rise: ".Length * font2.Width, y, sunRise, font2, 255, 255, 0, 0, 0, blue);

                        y += font2.Height + 2;
                        matrix.DrawText(2, y, "Sun Set:  ", font2, 128, 128, 128, 0, 0, blue);
                        matrix.DrawText(2 + "Sun Set:  ".Length * font2.Width, y, sunSet, font2, 255, 255, 0, 0, 0, blue);

                        Thread.Sleep(4000);

                        ScrollText(
                            matrix,
                            s_citiesData[cityIndex].City,
                            font,
                            pos,
                            -(pos + s_citiesData[cityIndex].City.Length * font.Width),
                            128, 128, 128, 0, 0, blue);

                        y = font.Height;
                        matrix.DrawText((matrix.Width - (temperature.Length + 1) * font1.Width) / 2, y, temperature + "\u00B0", font1, 0, 0, blue, 0, 0, blue);

                        y += font1.Height + 2;
                        matrix.DrawText(2, y, description, font2, 0, 0, blue, 0, 0, blue);

                        y += font2.Height + 2;
                        matrix.DrawText(2, y, "humidity: ", font2, 0, 0, blue, 0, 0, blue);
                        matrix.DrawText(font2.Width * "humidity: ".Length + 2, y, humidity, font2, 0, 0, blue, 0, 0, blue);

                        y += font2.Height;
                        matrix.DrawText((matrix.Width - localTime.Length * font.Width) / 2, y, localTime, font, 0, 0, blue, 0, 0, blue);

                        y += font.Height + 2;
                        matrix.DrawText(2, y, "Sun Rise: ", font2, 0, 0, blue, 0, 0, blue);
                        matrix.DrawText(2 + "Sun Rise: ".Length * font2.Width, y, sunRise, font2, 0, 0, blue, 0, 0, blue);

                        y += font2.Height + 2;
                        matrix.DrawText(2, y, "Sun Set:  ", font2, 0, 0, blue, 0, 0, blue);
                        matrix.DrawText(2 + "Sun Set:  ".Length * font2.Width, y, sunSet, font2, 0, 0, blue, 0, 0, blue);

                        cityIndex = (cityIndex + 1) % s_citiesData.Length;
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }