commit cdf3c217563b42de9a66470b932a0fa637363089
Author: A-Konig <alex-nebulae@seznam.cz>
Date:   Mon May 10 20:08:11 2021 +0200

    re #8841 Fixing errors in start/end time and adding interfaces for DataParser and JsonParser

diff --git a/Server/ServerApp/Parser/InputData/CsvDataLoader.cs b/Server/ServerApp/Parser/InputData/CsvDataLoader.cs
index 91b5749..b196784 100644
--- a/Server/ServerApp/Parser/InputData/CsvDataLoader.cs
+++ b/Server/ServerApp/Parser/InputData/CsvDataLoader.cs
@@ -1,4 +1,8 @@
-﻿using System;
+﻿//
+// Author: A. Konig
+//
+
+using System;
 using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
@@ -8,8 +12,8 @@ namespace ServerApp.Parser.InputData
     /// <summary>
     /// Class responsible for loading data from file
     /// </summary>
-    /// <author>Alex Konig</author>
-    class CsvDataLoader : DataLoader
+    /// <author>A. Konig</author>
+    class CsvDataLoader : IDataLoader
     {
         /// <summary> Culture info for parsing numbers </summary>
         static CultureInfo cultureInfo = new CultureInfo("de-DE");
diff --git a/Server/ServerApp/Parser/InputData/DataLoader.cs b/Server/ServerApp/Parser/InputData/DataLoader.cs
deleted file mode 100644
index fbf4c47..0000000
--- a/Server/ServerApp/Parser/InputData/DataLoader.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace ServerApp.Parser.InputData
-{
-    /// <author>Alex Konig</author>
-    interface DataLoader
-    {
-        /// <summary>
-        /// Load jis data from file
-        /// </summary>
-        /// <param name="pathToFile">Path to file</param>
-        /// <returns></returns>
-        List<JisInstance> LoadJisFile(string pathToFile);
-
-        /// <summary>
-        /// Load login data from file
-        /// </summary>
-        /// <param name="pathToFile">Path to file</param>
-        /// <returns></returns>
-        List<LogInInstance> LoadLoginFile(string pathToFile);
-        /// <summary>
-        /// Load weather data from file
-        /// </summary>
-        /// <param name="pathToFile">Path to file</param>
-        /// <returns></returns>
-        List<WeatherInstance> LoadWeatherFile(string pathToFile);
-
-    }
-}
diff --git a/Server/ServerApp/Parser/InputData/IDataLoader.cs b/Server/ServerApp/Parser/InputData/IDataLoader.cs
new file mode 100644
index 0000000..f0772dd
--- /dev/null
+++ b/Server/ServerApp/Parser/InputData/IDataLoader.cs
@@ -0,0 +1,36 @@
+﻿//
+// Author: A. Konig
+//
+
+using System.Collections.Generic;
+
+namespace ServerApp.Parser.InputData
+{
+    /// <summary>
+    /// Interface that every DataLoader should implement
+    /// </summary>
+    /// <author>A. Konig</author>
+    interface IDataLoader
+    {
+        /// <summary>
+        /// Load jis data from file
+        /// </summary>
+        /// <param name="pathToFile">Path to file</param>
+        /// <returns></returns>
+        List<JisInstance> LoadJisFile(string pathToFile);
+
+        /// <summary>
+        /// Load login data from file
+        /// </summary>
+        /// <param name="pathToFile">Path to file</param>
+        /// <returns></returns>
+        List<LogInInstance> LoadLoginFile(string pathToFile);
+        /// <summary>
+        /// Load weather data from file
+        /// </summary>
+        /// <param name="pathToFile">Path to file</param>
+        /// <returns></returns>
+        List<WeatherInstance> LoadWeatherFile(string pathToFile);
+
+    }
+}
diff --git a/Server/ServerApp/Parser/InputData/JisInstance.cs b/Server/ServerApp/Parser/InputData/JisInstance.cs
index 749e693..82af5e9 100644
--- a/Server/ServerApp/Parser/InputData/JisInstance.cs
+++ b/Server/ServerApp/Parser/InputData/JisInstance.cs
@@ -1,4 +1,8 @@
-﻿using System;
+﻿//
+// Author: A. Konig
+//
+
+using System;
 
 namespace ServerApp.Parser.InputData
 {
@@ -13,7 +17,7 @@ namespace ServerApp.Parser.InputData
     ///     "A1";"08.04.2018 14:23:15";1
     ///     [place tag];[date time];[amount]
     /// </summary>
-    /// <author>Alex Konig</author>
+    /// <author>A. Konig</author>
     class JisInstance
     {
         /// <summary> Place tag  </summary>
diff --git a/Server/ServerApp/Parser/InputData/LogInInstance.cs b/Server/ServerApp/Parser/InputData/LogInInstance.cs
index 40ef483..7fba2c2 100644
--- a/Server/ServerApp/Parser/InputData/LogInInstance.cs
+++ b/Server/ServerApp/Parser/InputData/LogInInstance.cs
@@ -1,4 +1,8 @@
-﻿using System;
+﻿//
+// Author: A. Konig
+//
+
+using System;
 
 namespace ServerApp.Parser.InputData
 {
@@ -20,7 +24,7 @@ namespace ServerApp.Parser.InputData
     ///     "27.10.2011 00:00:00";1;7;"13:00";"13:45";"UI";"Laboratoř";"UI-505";"ui505av07-lps"
     ///     [datum];[amount];[lesson];[lesson start];[lesson end];[building];[room type];[room];[hostname]
     /// </summary>
-    /// <author>Alex Konig</author>
+    /// <author>A. Konig</author>
     class LogInInstance
     {
         /// <summary> Date time </summary>
diff --git a/Server/ServerApp/Parser/InputData/WeatherInstance.cs b/Server/ServerApp/Parser/InputData/WeatherInstance.cs
index cdb4af4..7ee6ef6 100644
--- a/Server/ServerApp/Parser/InputData/WeatherInstance.cs
+++ b/Server/ServerApp/Parser/InputData/WeatherInstance.cs
@@ -1,4 +1,8 @@
-﻿using System;
+﻿//
+// Author: A. Konig
+//
+
+using System;
 
 namespace ServerApp.Parser.InputData
 {
@@ -9,7 +13,7 @@ namespace ServerApp.Parser.InputData
     ///     "30.04.2019 16:19:01";20.3;5.3;0;19
     ///     [date time];[temperature];[wind];[rain];[luminance]
     /// </summary>
-    /// <author>Alex Konig</author>
+    /// <author>A. Konig</author>
     class WeatherInstance
     {
         /// <summary> Date and time </summary>
diff --git a/Server/ServerApp/Parser/OutputInfo/ActivityInfo.cs b/Server/ServerApp/Parser/OutputInfo/ActivityInfo.cs
index 1e287e0..6d17e4f 100644
--- a/Server/ServerApp/Parser/OutputInfo/ActivityInfo.cs
+++ b/Server/ServerApp/Parser/OutputInfo/ActivityInfo.cs
@@ -1,4 +1,8 @@
-﻿using System;
+﻿//
+// Author: A. Konig
+//
+
+using System;
 
 namespace ServerApp.Parser.OutputInfo
 {
@@ -6,7 +10,7 @@ namespace ServerApp.Parser.OutputInfo
     /// Class representing the number of events in a given time interval a given faculty
     /// - shortest possible interval is 1h
     /// </summary>
-    /// <author>Alex Konig</author>
+    /// <author>A. Konig</author>
     class ActivityInfo
     {
         /// <summary> Building </summary>
diff --git a/Server/ServerApp/Parser/OutputInfo/ValueToConditions.cs b/Server/ServerApp/Parser/OutputInfo/ValueToConditions.cs
new file mode 100644
index 0000000..09c0813
--- /dev/null
+++ b/Server/ServerApp/Parser/OutputInfo/ValueToConditions.cs
@@ -0,0 +1,74 @@
+﻿//
+// Author: A. Konig
+//
+
+namespace ServerApp.Parser.OutputInfo
+{
+    /// <summary>
+    /// Transfers various values to weather conditions and vice versa
+    /// </summary>
+    /// <author>A. Konig</author>
+    public static class ValueToConditions
+    {
+        /// <summary>
+        /// Lux to weather conditions
+        /// </summary>
+        /// <param name="lux">Lux value</param>
+        /// <returns>Weather conditions</returns>
+        public static WeatherConditions TransferLuxToConditions(double lux)
+        {
+            if (lux > 40_000)
+                return WeatherConditions.Sunny;
+
+            if (lux > 20_000)
+                return WeatherConditions.Cloudy;
+
+            // TODO tohle bylo 10_000, jak mi to má vycházet, zkusit na hourly data
+            if (lux != 0)
+                return WeatherConditions.Overcast;
+
+            return WeatherConditions.Dark;
+        }
+
+        /// <summary>
+        /// Weather conditions to average lux
+        /// </summary>
+        /// <param name="condition">Weather conditions</param>
+        /// <returns>Lux value</returns>
+        internal static double TransferConditionsToLux(WeatherConditions condition)
+        {
+            if (condition == WeatherConditions.Sunny)
+                return 60_000;
+
+            if (condition == WeatherConditions.Cloudy)
+                return 30_000;
+
+            if (condition == WeatherConditions.Overcast)
+                return 10_000;
+
+            if (condition == WeatherConditions.Dark)
+                return 0;
+
+            return -1;
+        }
+
+        /// <summary>
+        /// Cloud cover value in percentage to weather conditions
+        /// </summary>
+        /// <param name="cloudCover">Value expected between 0-100</param>
+        /// <returns>WeatherConditions</returns>
+        internal static WeatherConditions CloudCoverToConditions(int cloudCover)
+        {
+            if (cloudCover >= 66)
+                return WeatherConditions.Overcast;
+
+            if (cloudCover >= 33)
+                return WeatherConditions.Cloudy;
+
+            if (cloudCover >= 0)
+                return WeatherConditions.Sunny;
+
+            return WeatherConditions.Dark;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Server/ServerApp/Parser/OutputInfo/WeatherConditions.cs b/Server/ServerApp/Parser/OutputInfo/WeatherConditions.cs
index c73cf37..6c8b760 100644
--- a/Server/ServerApp/Parser/OutputInfo/WeatherConditions.cs
+++ b/Server/ServerApp/Parser/OutputInfo/WeatherConditions.cs
@@ -1,74 +1,15 @@
-﻿namespace ServerApp.Parser.OutputInfo
+﻿//
+// Author: A. Konig
+//
+
+namespace ServerApp.Parser.OutputInfo
 {
     /// <summary>
     /// Weather conditions in regards to sun level
     /// </summary>
-    /// <author>Alex Konig</author>
+    /// <author>A. Konig</author>
     public enum WeatherConditions
     {
         Sunny, Cloudy, Overcast, Dark
     }
-
-    /// <summary>
-    /// Transfers lux values to weather conditions and vice versa
-    /// </summary>
-    /// <author>Alex Konig</author>
-    public static class ValueToConditions
-    {
-        /// <summary>
-        /// Lux to weather conditions
-        /// </summary>
-        /// <param name="lux">Lux value</param>
-        /// <returns>Weather conditions</returns>
-        public static WeatherConditions TransferLuxToConditions(double lux)
-        {
-            if (lux > 40_000)
-                return WeatherConditions.Sunny;
-
-            if (lux > 20_000)
-                return WeatherConditions.Cloudy;
-
-            // TODO tohle bylo 10_000, jak mi to má vycházet, zkusit na hourly data
-            if (lux != 0)
-                return WeatherConditions.Overcast;
-
-            return WeatherConditions.Dark;
-        }
-
-        /// <summary>
-        /// Weather conditions to average lux
-        /// </summary>
-        /// <param name="condition">Weather conditions</param>
-        /// <returns>Lux value</returns>
-        internal static double TransferConditionsToLux(WeatherConditions condition)
-        {
-            if (condition == WeatherConditions.Sunny)
-                return 60_000;
-
-            if (condition == WeatherConditions.Cloudy)
-                return 30_000;
-
-            if (condition == WeatherConditions.Overcast)
-                return 10_000;
-
-            if (condition == WeatherConditions.Dark)
-                return 0;
-
-            return -1;
-        }
-
-        internal static WeatherConditions CloudCoverToConditions(int cloudCover)
-        {
-            if (cloudCover >= 66)
-                return WeatherConditions.Overcast;
-
-            if (cloudCover >= 33)
-                return WeatherConditions.Cloudy;
-
-            if (cloudCover >= 0)
-                return WeatherConditions.Sunny;
-
-            return WeatherConditions.Dark;
-        }
-    }
 }
\ No newline at end of file
diff --git a/Server/ServerApp/Parser/OutputInfo/WeatherInfo.cs b/Server/ServerApp/Parser/OutputInfo/WeatherInfo.cs
index 3db029c..52d70cd 100644
--- a/Server/ServerApp/Parser/OutputInfo/WeatherInfo.cs
+++ b/Server/ServerApp/Parser/OutputInfo/WeatherInfo.cs
@@ -1,4 +1,8 @@
-﻿using System;
+﻿//
+// Author: A. Konig
+//
+
+using System;
 
 namespace ServerApp.Parser.OutputInfo
 {
@@ -6,7 +10,7 @@ namespace ServerApp.Parser.OutputInfo
     /// Class representing the weather in a given interval at ZCU
     /// - shortest possible interval is 1h
     /// </summary>
-    /// <author>Alex Konig</author>
+    /// <author>A. Konig</author>
     class WeatherInfo
     {
         /// <summary> Temperature in °C </summary>
diff --git a/Server/ServerApp/Parser/Parsers/DataParser.cs b/Server/ServerApp/Parser/Parsers/DataParser.cs
index 015ddf3..48bd17a 100644
--- a/Server/ServerApp/Parser/Parsers/DataParser.cs
+++ b/Server/ServerApp/Parser/Parsers/DataParser.cs
@@ -1,4 +1,9 @@
-﻿using ServerApp.Parser.InputData;
+﻿//
+// Author: A. Konig
+//
+
+using ServerApp.DataDownload;
+using ServerApp.Parser.InputData;
 using ServerApp.Parser.OutputInfo;
 using System;
 using System.Collections.Generic;
@@ -11,11 +16,12 @@ namespace ServerApp.Parser.Parsers
     /// Class parsing data files into instances of ActivityInfo and WeatherInfo divided by given time interval
     /// Data parsed from 7am (included) to 18pm (included)
     /// </summary>
-    /// <author>Alex Konig</author>
-    class DataParser
+    /// <author>A. Konig</author>
+    class DataParser : IDataParser
     {
-        /// <summary> Path to data folder </summary>
-        string path;
+        /// <summary> Data downloader </summary>
+        DataDownloader downloader;
+
         /// <summary> Weather data parser </summary>
         WeatherParser weatherParser;
         /// <summary> Jis data parser </summary>
@@ -25,26 +31,27 @@ namespace ServerApp.Parser.Parsers
 
         /// <summary> WeatherInfo </summary>
         List<WeatherInfo> weatherList;
-        public List<WeatherInfo> WeatherList { get => weatherList; }
+        public new List<WeatherInfo> WeatherList { get => weatherList; }
         /// <summary> ActivityInfo repersenting overall activity </summary>
         List<ActivityInfo> attendanceList;
-        public List<ActivityInfo> AttendanceList { get => attendanceList; }
+        public new List<ActivityInfo> AttendanceList { get => attendanceList; }
 
         /// <summary> ActivityInfo representing jis activity </summary>
         List<ActivityInfo> jisList;
         /// <summary> ActivityInfo representing login activity</summary>
         List<ActivityInfo> loginList;
 
+
         /// <summary>
         /// Constructor
         /// </summary>
-        public DataParser(string path)
+        public DataParser(DataDownloader downloader)
         {
+            this.downloader = downloader;
+
             TagInfo.CreateDictionaries();
 
-            // TODO ask for data folder
-            this.path = path;
-            DataLoader loader = new CsvDataLoader();
+            IDataLoader loader = new CsvDataLoader();
 
             weatherParser = new WeatherParser(loader);
             jisParser = new JisParser(loader);
@@ -56,26 +63,35 @@ namespace ServerApp.Parser.Parsers
         /// </summary>
         /// <param name="interval">Length of an interval</param>
         /// <param name="wholeDay">Parse data as one instance per day</param>
-        public bool Parse(DateTime startTime, DateTime endTime, int interval = 1, bool wholeDay = true)
+        /// <param name="endTime">End time of related data</param>
+        /// <param name="startTime">Start time of related data</param>
+        override public bool Parse(DateTime startTime, DateTime endTime, int interval = 1, bool wholeDay = true)
         {
-            // TODO start and end time -> ask for files from this span, plus validate if the data really is from this span (issue with 00 files)
 
             var cultureInfo = CultureInfo.GetCultureInfo("en-GB");
             Thread.CurrentThread.CurrentCulture = cultureInfo;
             Thread.CurrentThread.CurrentUICulture = cultureInfo;
 
-            string pathWeather = path + "weather";
-            string pathJis = path + "jis";
-            string pathLogIn = path + "login";
+            // get path to folder w/ datafiles
+            string pathWeather = downloader.DataSubDirectories[DataType.POCASI]; // path + "weather";
+            string pathJis = downloader.DataSubDirectories[DataType.JIS]; // path + "jis";
+            string pathLogIn = downloader.DataSubDirectories[DataType.STROJE]; // path + "login";
+
+            // get all files that should be parsed
+            Date start = new Date((uint)startTime.Month, (uint)startTime.Year);
+            Date end = new Date((uint)endTime.Month, (uint)endTime.Year);
+            var weatherFiles = downloader.GetData(pathWeather, start, end);
+            var jisFiles = downloader.GetData(pathJis, start, end);
+            var loginFiles = downloader.GetData(pathLogIn, start, end);
 
-            weatherList = weatherParser.ParseWeatherData(pathWeather, wholeDay, interval);
-            jisList = jisParser.ParseJisData(pathJis, wholeDay, interval);
-            loginList = loginParser.ParseLogInData(pathLogIn, wholeDay, interval);
+            weatherList = weatherParser.ParseWeatherData(weatherFiles, startTime, endTime, wholeDay, interval);
+            jisList = jisParser.ParseJisData(jisFiles, startTime, endTime, wholeDay, interval);
+            loginList = loginParser.ParseLogInData(loginFiles, startTime, endTime, wholeDay, interval);
 
             //Console.WriteLine("WEATHER");
             //WriteToConsole(weatherList);
-            //Console.WriteLine("JIS");
-            //WriteToConsole(jisList);
+            Console.WriteLine("JIS");
+            WriteToConsole(jisList);
             //Console.WriteLine("LOGIN");
             //WriteToConsole(loginList);
 
@@ -83,8 +99,8 @@ namespace ServerApp.Parser.Parsers
 
             MergeAttendance();
 
-            //Console.WriteLine("MERGED IN ONE LIST");
-            //WriteToConsole(attendanceList);
+            Console.WriteLine("MERGED IN ONE LIST");
+            WriteToConsole(attendanceList);
 
             if (weatherList.Count == 0 || attendanceList.Count == 0)
                 return false;
diff --git a/Server/ServerApp/Parser/Parsers/IDataParser.cs b/Server/ServerApp/Parser/Parsers/IDataParser.cs
new file mode 100644
index 0000000..a4d7fb8
--- /dev/null
+++ b/Server/ServerApp/Parser/Parsers/IDataParser.cs
@@ -0,0 +1,34 @@
+﻿//
+// Author: A. Konig
+//
+
+using ServerApp.Parser.OutputInfo;
+using System;
+using System.Collections.Generic;
+
+namespace ServerApp.Parser.Parsers
+{
+    /// <summary>
+    /// Abstract class that every DataParser should inherit from
+    /// </summary>
+    /// <author>A. Konig</author>
+    abstract class IDataParser
+    {
+        /// <summary> WeatherInfo </summary>
+        List<WeatherInfo> weatherList;
+        public List<WeatherInfo> WeatherList { get => weatherList; }
+        /// <summary> ActivityInfo repersenting overall activity </summary>
+        List<ActivityInfo> attendanceList;
+        public List<ActivityInfo> AttendanceList { get => attendanceList; }
+
+        /// <summary>
+        /// Parse data
+        /// </summary>
+        /// <param name="interval">Length of an interval</param>
+        /// <param name="wholeDay">Parse data as one instance per day</param>
+        /// <param name="endTime">End time of related data</param>
+        /// <param name="startTime">Start time of related data</param>
+        public abstract bool Parse(DateTime startTime, DateTime endTime, int interval = 1, bool wholeDay = true);
+
+    }
+}
diff --git a/Server/ServerApp/Parser/Parsers/JisParser.cs b/Server/ServerApp/Parser/Parsers/JisParser.cs
index ef13593..1a2914d 100644
--- a/Server/ServerApp/Parser/Parsers/JisParser.cs
+++ b/Server/ServerApp/Parser/Parsers/JisParser.cs
@@ -1,4 +1,8 @@
-﻿using System;
+﻿//
+// Author: A. Konig
+//
+
+using System;
 using System.Collections.Generic;
 using System.IO;
 using ServerApp.Parser.InputData;
@@ -10,18 +14,18 @@ namespace ServerApp.Parser.Parsers
     /// Class parsing jis files into instances of ActivityInfo divided by given time interval
     /// Data parsed from 7am (included) to 18pm (included)
     /// </summary>
-    /// <author>Alex Konig</author>
+    /// <author>A. Konig</author>
     class JisParser
     {
 
         /// <summary> Datafile loader  </summary>
-        DataLoader loader;
+        IDataLoader loader;
 
         /// <summary>
         /// Constructor
         /// </summary>
         /// <param name="loader">Datafile loader</param>
-        public JisParser(DataLoader loader)
+        public JisParser(IDataLoader loader)
         {
             this.loader = loader;
         }
@@ -30,29 +34,32 @@ namespace ServerApp.Parser.Parsers
         /// Parses jis data to ActivityInfo instances
         /// Data parsed from 7am (included) to 18pm (included)
         /// </summary>
-        /// <param name="folder">Folder with login data files</param>
+        /// <param name="jisFiles">Paths to files with login data files</param>
+        /// <param name="endTime">End time of related data</param>
+        /// <param name="startTime">Start time of related data</param>
         /// <param name="wholeDay">Should data be parsed as one instance per day (if true parameter interval will be ignored)</param>
         /// <param name="interval">Time interval to divide days by, minimum is 1h</param>
         /// <returns></returns>
-        public List<ActivityInfo> ParseJisData(string folder, bool wholeDay = true, int interval = 1)
+        public List<ActivityInfo> ParseJisData(List<string> jisFiles, DateTime startTime, DateTime endTime, bool wholeDay = true, int interval = 1)
         {
-            if (!Directory.Exists(folder))
-                return null;
-
             List<ActivityInfo> list = new List<ActivityInfo>();
 
+            if (jisFiles == null || startTime == null || endTime == null || interval <= 0)
+                return list;
+
             // parse all files
-            string[] fileEntries = Directory.GetFiles(folder);
-            foreach (string fileName in fileEntries)
+            foreach (string fileName in jisFiles)
             {
-                List<ActivityInfo> loadedData = null;
-
+                if (!File.Exists(fileName))
+                    continue;
+                
                 // parse as one instance per day
+                List<ActivityInfo> loadedData = null;
                 if (wholeDay)
-                    loadedData = ProcessOneJisFileAsDays(fileName);
+                    loadedData = ProcessOneJisFileAsDays(fileName, startTime, endTime);
                 // parse by interval length
                 else
-                    loadedData = ProcessOneJisFileAsIntervals(fileName, interval);
+                    loadedData = ProcessOneJisFileAsIntervals(fileName, interval, startTime, endTime);
 
                 list.AddRange(loadedData);
             }
@@ -63,14 +70,17 @@ namespace ServerApp.Parser.Parsers
         /// <summary>
         /// Parses data from one data file as one instance per day
         /// </summary>
-        /// <param name="path">Path ti file</param>
+        /// <param name="path">Path to file</param>
+        /// <param name="endTime">End time of related data</param>
+        /// <param name="startTime">Start time of related data</param>
         /// <returns>List with ActivityInfo instances</returns>
-        private List<ActivityInfo> ProcessOneJisFileAsDays(string path)
+        private List<ActivityInfo> ProcessOneJisFileAsDays(string path, DateTime startTime, DateTime endTime)
         {
+            List<ActivityInfo> jisInfo = new List<ActivityInfo>();
+            
             if (!File.Exists(path))
-                return null;
+                return jisInfo;
 
-            List<ActivityInfo> jisInfo = new List<ActivityInfo>();
             List<JisInstance> list =  loader.LoadJisFile(path);
 
             // data for each faculty
@@ -104,6 +114,10 @@ namespace ServerApp.Parser.Parsers
                     lastStartTime = date;
                 }
 
+                // if not in allowed time window -> discard
+                if (list[i].dateTime < startTime || list[i].dateTime > endTime)
+                    continue;
+
                 // aggregate data
                 if (TagInfo.jisPlaces.ContainsKey(place))
                 {
@@ -138,13 +152,16 @@ namespace ServerApp.Parser.Parsers
         /// </summary>
         /// <param name="path">Path ti file</param>
         /// <param name="interval">Interval length</param>
+        /// <param name="endTime">End time of related data</param>
+        /// <param name="startTime">Start time of related data</param>
         /// <returns>List with ActivityInfo instances</returns>
-        private List<ActivityInfo> ProcessOneJisFileAsIntervals(string path, int interval)
+        private List<ActivityInfo> ProcessOneJisFileAsIntervals(string path, int interval, DateTime startTime, DateTime endTime)
         {
+            List<ActivityInfo> jisInfo = new List<ActivityInfo>();
+            
             if (!File.Exists(path))
-                return null;
+                return jisInfo;
 
-            List<ActivityInfo> jisInfo = new List<ActivityInfo>();
             List<JisInstance> list = loader.LoadJisFile(path);
 
             // data for each faculty
@@ -164,7 +181,7 @@ namespace ServerApp.Parser.Parsers
             // first day
             DateTime lastStartTime = new DateTime(list[0].dateTime.Year, list[0].dateTime.Month, list[0].dateTime.Day, minmaxHour[0], 0, 0);
             int endtime = to[0];
-            int startTime = minmaxHour[0];
+            int startingTime = minmaxHour[0];
             int index = 0;
             for (int i = 0; i < list.Count; i++)
             {
@@ -188,7 +205,7 @@ namespace ServerApp.Parser.Parsers
                 if ( date.Hour >= endtime || trigger) 
                 {
                     // start time of last interval
-                    DateTime stTime = new DateTime(lastStartTime.Year, lastStartTime.Month, lastStartTime.Day, startTime, 0, 0);
+                    DateTime stTime = new DateTime(lastStartTime.Year, lastStartTime.Month, lastStartTime.Day, startingTime, 0, 0);
 
                     // find end and start time
                     if (!trigger)
@@ -198,9 +215,9 @@ namespace ServerApp.Parser.Parsers
 
                     endtime = to[index];
                     if (index == 0)
-                        startTime = minmaxHour[0];
+                        startingTime = minmaxHour[0];
                     else
-                        startTime = to[index - 1];
+                        startingTime = to[index - 1];
 
                     // data for each faculty separate
                     for (int k = 0; k < TagInfo.buildings.Length; k++)
@@ -213,6 +230,10 @@ namespace ServerApp.Parser.Parsers
                     lastStartTime = date;
                 }
 
+                // if not in allowed time window -> discard
+                if (list[i].dateTime < startTime || list[i].dateTime > endTime)
+                    continue;
+
                 // aggregate data
                 if (TagInfo.jisPlaces.ContainsKey(place))
                 {
diff --git a/Server/ServerApp/Parser/Parsers/JsonParser.cs b/Server/ServerApp/Parser/Parsers/JsonParser.cs
deleted file mode 100644
index ac3b029..0000000
--- a/Server/ServerApp/Parser/Parsers/JsonParser.cs
+++ /dev/null
@@ -1,390 +0,0 @@
-﻿using ServerApp.DataDownload;
-using ServerApp.Parser.OutputInfo;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Net;
-using System.Text.Json;
-using static System.Text.Json.JsonElement;
-
-namespace ServerApp.Parser.Parsers
-{
-    /// <summary>
-    /// Class representing a parser for json prediction data
-    /// </summary>
-    /// <author>A. Konig</author>
-    class JsonParser
-    {
-        /// <summary> Current weather </summary>
-        public WeatherInfo current;
-        /// <summary> Prediction for today, tommorrow and day after tommorrow </summary>
-        public List<WeatherInfo> predictions;
-        
-        /// <summary> Data loader </summary>
-        DataDownloader loader;
-        /// <summary> Currently parsed day </summary>
-        DateTime currParsedDay;
-        /// <summary> Sunrise time of currently parsed day </summary>
-        DateTime sunriseTime;
-        /// <summary> Sunset time of currently parsed day </summary>
-        DateTime sunsetTime;
-
-        /// <summary>
-        /// Constructor
-        /// </summary>
-        /// <param name="loader"></param>
-        public JsonParser(DataDownloader loader)
-        {
-            this.loader = loader;
-        }
-
-        /// <summary>
-        /// Parse weather prediction
-        /// Results is in attributes current for current weather and pred for weather prediction for today, tommorrow and day after tommorrow
-        /// </summary>
-        public void ParsePrediction()
-        {
-            // TODO ask DataDownloader for download said file and return path to it
-            
-            // get file
-            string file = DownloadWeatherPrediction();
-            DateTime now = DateTime.Now;
-            Console.WriteLine(File.Exists(file));
-
-            // parse file
-            string data = File.ReadAllText(file);
-
-            JsonDocument doc = JsonDocument.Parse(data);
-            JsonElement root = doc.RootElement;
-            var weatherP = root.EnumerateObject();
-            predictions = new List<WeatherInfo>();
-
-            while (weatherP.MoveNext())
-            {
-                string name = weatherP.Current.Name;
-                Console.WriteLine(name);
-
-                switch (name)
-                {
-                    // current weather
-                    case "current_condition":
-                        {
-                            ArrayEnumerator currentWeather = weatherP.Current.Value.EnumerateArray();
-                            current = ParseCurrentWeather(currentWeather);
-
-                            break;
-
-                        }
-                    // weather prediction
-                    case "weather":
-                        {
-                            ArrayEnumerator weather = weatherP.Current.Value.EnumerateArray();
-                            ParseWeatherPredict(weather);
-
-                            break;
-                        }
-                }
-            }
-
-            // sunrise + sunset into data
-            EncompassSunRiseSetTimes();
-
-            TestConsoleOutput();
-        }
-
-        private void TestConsoleOutput()
-        {
-            Console.WriteLine(current);
-            foreach (WeatherInfo w in predictions)
-                Console.WriteLine(w);
-        }
-
-        // TODO move to data loader
-        /// <summary>
-        /// Downloads json file
-        /// </summary>
-        /// <returns> Path to file </returns>
-        private string DownloadWeatherPrediction()
-        {
-            DateTime now = DateTime.Now;
-            WebClient webClient = new WebClient();
-            webClient.DownloadFile("http://wttr.in/Plzen,czechia?format=j1", $"data/{now.Year}{now.Month}{now.Day}.json");
-
-            return $"data/{now.Year}{now.Month}{now.Day}.json";
-        }
-
-        /// <summary>
-        /// Change data in a way that they now reflect sunrise and sunset times
-        /// If current time under sunrise or over sunset -> WeatherConditions is Dark
-        /// If prediction time is under sunrise or over sunset and more than half of the interval is under/over said time -> WeatherCondition is Dark
-        /// </summary>
-        private void EncompassSunRiseSetTimes()
-        {
-            // change current weather
-            if ((current.startTime.TimeOfDay > sunsetTime.TimeOfDay) || (current.startTime.TimeOfDay < sunriseTime.TimeOfDay))
-                current.condition = WeatherConditions.Dark;
-
-            // change prediction
-            for (int i = 0; i < predictions.Count - 1; i++)
-            {
-                WeatherInfo w = predictions[i];
-                WeatherInfo wNext = predictions[i + 1];
-
-                // if wNext time < than w time then it is prediction from the next day -> add 24 to correctly calculate timespan
-                int timespan = wNext.startTime.Hour - w.startTime.Hour;
-                if (wNext.startTime.Hour < w.startTime.Hour)
-                    timespan = (wNext.startTime.Hour+24) - w.startTime.Hour;
-                
-                w.intervalLength = timespan;
-
-                // if start under sunset
-                if (w.startTime.TimeOfDay > sunsetTime.TimeOfDay)
-                    w.condition = WeatherConditions.Dark;
-
-                // if start under sunrise
-                if (w.startTime.TimeOfDay < sunriseTime.TimeOfDay)
-                {
-                    double howMuch = ((sunriseTime.Hour * 60 + sunriseTime.Minute) - (w.startTime.Hour * 60 + w.startTime.Minute)) / 60.0;
-
-                    if (howMuch >= timespan / 2.0)
-                        w.condition = WeatherConditions.Dark;
-                }
-
-                // if start under sunrise
-                TimeSpan endTime = new TimeSpan(w.startTime.TimeOfDay.Hours + timespan, w.startTime.TimeOfDay.Minutes, 0);
-                if (endTime > sunsetTime.TimeOfDay)
-                {
-                    double howMuch = ((endTime.Hours * 60 + endTime.Minutes) - (sunsetTime.Hour * 60 + sunsetTime.Minute)) / 60.0;
-
-                    if (howMuch >= timespan / 2.0)
-                        w.condition = WeatherConditions.Dark;
-                }
-            }
-
-            // last prediction
-            WeatherInfo wLast = predictions[predictions.Count - 1];
-            TimeSpan endTimeW = new TimeSpan(24, 0, 0);
-            int timespanLast = endTimeW.Hours - wLast.startTime.Hour;
-            wLast.intervalLength = timespanLast;
-
-            // if start under sunset
-            if (wLast.startTime.TimeOfDay > sunsetTime.TimeOfDay)
-                wLast.condition = WeatherConditions.Dark;
-
-            // if start under sunrise
-            if (wLast.startTime.TimeOfDay < sunriseTime.TimeOfDay)
-            {
-                double howMuch = ((sunriseTime.Hour * 60 + sunriseTime.Minute) - (wLast.startTime.Hour * 60 + wLast.startTime.Minute)) / 60.0;
-
-                if (howMuch >= timespanLast / 2.0)
-                    wLast.condition = WeatherConditions.Dark;
-            }
-
-            // if start under sunrise
-            if (endTimeW > sunsetTime.TimeOfDay)
-            {
-                double howMuch = ((endTimeW.Hours * 60 + endTimeW.Minutes) - (sunsetTime.Hour * 60 + sunsetTime.Minute)) / 60.0;
-
-                if (howMuch >= timespanLast / 2.0)
-                    wLast.condition = WeatherConditions.Dark;
-            }
-        }
-
-        /// <summary>
-        /// Parse weather prediction
-        /// </summary>
-        /// <param name="weather"> ArrayEnumerator of weather predictions </param>
-        private void ParseWeatherPredict(ArrayEnumerator weather)
-        {
-            while (weather.MoveNext())
-            {
-                // prediction for one day
-                var obj = weather.Current.EnumerateObject();
-
-                while (obj.MoveNext())
-                {
-                    switch (obj.Current.Name)
-                    {
-                        case "date":
-                            {
-                                DateTime.TryParseExact(obj.Current.Value.GetString(), "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out currParsedDay);
-                                break;
-                            }
-                        // hourly predictions
-                        case "hourly":
-                            {
-                                ParseHourly(obj.Current.Value.EnumerateArray());
-                                break;
-                            }
-                        // sunset / sunrise hours
-                        case "astronomy":
-                            {
-                                ParseAstronomy(obj.Current.Value.EnumerateArray());
-                                break;
-                            }
-                    }
-                }
-            }
-        }
-
-        /// <summary>
-        /// Parse sunrise and sunset times
-        /// </summary>
-        /// <param name="astronomy"> Astronomy array enumerator </param>
-        private void ParseAstronomy(ArrayEnumerator astronomy)
-        {
-            while (astronomy.MoveNext())
-            {
-                var astrInfo = astronomy.Current.EnumerateObject();
-                
-                while (astrInfo.MoveNext())
-                {
-                    switch (astrInfo.Current.Name)
-                    {
-                        case "sunrise":
-                            {
-                                DateTime.TryParseExact(astrInfo.Current.Value.GetString(), "hh:mm tt", CultureInfo.InvariantCulture, DateTimeStyles.None, out sunriseTime);
-                                Console.WriteLine("\t sunrise time : " + sunriseTime + " " + astrInfo.Current.Value.GetString());
-                                break;
-                            }
-                        case "sunset":
-                            {
-                                DateTime.TryParseExact(astrInfo.Current.Value.GetString(), "hh:mm tt", CultureInfo.InvariantCulture, DateTimeStyles.None, out sunsetTime);
-                                Console.WriteLine("\t sunset time : " + sunsetTime + " " + astrInfo.Current.Value.GetString());
-                                break;
-                            }
-                    }
-                }
-            }
-        }
-
-        /// <summary>
-        /// Parse hourly predictions
-        /// </summary>
-        /// <param name="hourly">Enumerated array of hourly predictions</param>
-        private void ParseHourly(ArrayEnumerator hourly)
-        {
-            while (hourly.MoveNext())
-            {
-                // one hourly prediction
-                var oneH = hourly.Current.EnumerateObject();
-                WeatherInfo weather = new WeatherInfo();
-
-                while (oneH.MoveNext())
-                {
-                    switch (oneH.Current.Name)
-                    {
-                        case "FeelsLikeC":
-                            {
-                                Double.TryParse(oneH.Current.Value.GetString(), out weather.temp);
-                                break;
-                            }
-                        case "cloudcover":
-                            {
-                                int cloudCover;
-                                Int32.TryParse(oneH.Current.Value.GetString(), out cloudCover);
-                                weather.condition = ValueToConditions.CloudCoverToConditions(cloudCover);
-                                break;
-                            }
-                        // take into account highest value from "chanceofrain" and "chaceofsnow"
-                        case "chanceofrain":
-                            {
-                                int rain;
-                                Int32.TryParse(oneH.Current.Value.GetString(), out rain);
-                                weather.rain = rain > weather.rain ? rain : weather.rain;
-                                break;
-                            }
-                        case "chanceofsnow":
-                            {
-                                int snow;
-                                Int32.TryParse(oneH.Current.Value.GetString(), out snow);
-                                weather.rain = snow > weather.rain ? snow : weather.rain;
-                                break;
-                            }
-                        // wind kmph has to be translated to mps
-                        case "WindGustKmph":
-                            {
-                                double windkmh;
-                                Double.TryParse(oneH.Current.Value.GetString(), out windkmh);
-                                weather.wind= windkmh * 1000 / (60.0*60.0);
-                                break;
-                            }
-                        case "time":
-                            {
-                                int h;
-                                Int32.TryParse(oneH.Current.Value.GetString(), out h);
-                                h /= 100;
-                                DateTime time = new DateTime(currParsedDay.Year, currParsedDay.Month, currParsedDay.Day, h, 0, 0);
-                                weather.startTime = time;
-                                break;
-                            }
-                    }
-                }
-
-                // Console.WriteLine(weather.ToString());
-                predictions.Add(weather);
-
-            }
-
-        }
-
-        /// <summary>
-        /// Parse current weather
-        /// </summary>
-        /// <param name="currentWeather">Enumerated hour of weather data</param>
-        /// <returns>WeatherInfo with current weather</returns>
-        private WeatherInfo ParseCurrentWeather(ArrayEnumerator currentWeather)
-        {
-            WeatherInfo res = new WeatherInfo();
-            //res.current = true;
-
-            while (currentWeather.MoveNext())
-            {
-                var obj = currentWeather.Current.EnumerateObject();
-
-                while (obj.MoveNext())
-                {
-                    switch (obj.Current.Name)
-                    {
-                        case "localObsDateTime":
-                            {
-                                DateTime.TryParse(obj.Current.Value.GetString(), out res.startTime);
-                                break;
-                            }
-                        case "FeelsLikeC":
-                            {
-                                Double.TryParse(obj.Current.Value.GetString(), out res.temp);
-                                break;
-                            }
-                        case "cloudcover":
-                            {
-                                int cloudCover;
-                                Int32.TryParse(obj.Current.Value.GetString(), out cloudCover);
-                                res.condition = ValueToConditions.CloudCoverToConditions(cloudCover);
-                                break;
-                            }
-                        case "precipMM":
-                            {
-                                double rainMM;
-                                Double.TryParse(obj.Current.Value.GetString(), out rainMM);
-                                res.rain = rainMM > 0 ? 100 : 0;
-                                break;
-                            }
-                        case "windspeedKmph":
-                            {
-                                double wind;
-                                Double.TryParse(obj.Current.Value.GetString(), out wind);
-                                res.wind = wind * 1000 / (60.0 * 60.0);
-                                break;
-                            }
-                    }
-                }
-
-            }
-
-            return res;
-        }
-
-    }
-}
diff --git a/Server/ServerApp/Parser/Parsers/LogInParser.cs b/Server/ServerApp/Parser/Parsers/LogInParser.cs
index d78c8a6..32e53a2 100644
--- a/Server/ServerApp/Parser/Parsers/LogInParser.cs
+++ b/Server/ServerApp/Parser/Parsers/LogInParser.cs
@@ -1,4 +1,8 @@
-﻿using ServerApp.Parser.InputData;
+﻿//
+// Author: A. Konig
+//
+
+using ServerApp.Parser.InputData;
 using ServerApp.Parser.OutputInfo;
 using System;
 using System.Collections.Generic;
@@ -10,17 +14,17 @@ namespace ServerApp.Parser.Parsers
     /// Class parsing login files into instances of ActivityInfo divided by given time interval
     /// Data parsed from 7am (included) to 18pm (included)
     /// </summary>
-    /// <author>Alex Konig</author>
+    /// <author>A. Konig</author>
     class LogInParser
     {
         /// <summary> Datafile loader  </summary>
-        DataLoader loader;
+        IDataLoader loader;
 
         /// <summary>
         /// Constructor
         /// </summary>
         /// <param name="loader">Datafile loader</param>
-        public LogInParser(DataLoader loader)
+        public LogInParser(IDataLoader loader)
         {
             this.loader = loader;
         }
@@ -29,29 +33,32 @@ namespace ServerApp.Parser.Parsers
         /// Parses login data to ActivityInfo instances
         /// Data parsed from 7am (included) to 18pm (included)
         /// </summary>
-        /// <param name="folder">Folder with login data files</param>
+        /// <param name="loginFiles">Paths to files with login data files</param>
+        /// <param name="endTime">End time of related data</param>
+        /// <param name="startTime">Start time of related data</param>
         /// <param name="wholeDay">Should data be parsed as one instance per day (if true parameter interval will be ignored)</param>
         /// <param name="interval">Time interval to divide days by, minimum is 1h</param>
         /// <returns></returns>
-        public List<ActivityInfo> ParseLogInData(string folder, bool wholeDay = true, int interval = 1)
+        public List<ActivityInfo> ParseLogInData(List<string> loginFiles, DateTime startTime, DateTime endTime, bool wholeDay = true, int interval = 1)
         {
-            if (!Directory.Exists(folder))
-                return null;
-            
             List<ActivityInfo> list = new List<ActivityInfo>();
 
-            // get all files in folder
-            string[] fileEntries = Directory.GetFiles(folder);
-            foreach (string fileName in fileEntries)
+            if (loginFiles == null || startTime == null || endTime == null || interval <= 0)
+                return list;
+
+            // for all files in folder
+            foreach (string fileName in loginFiles)
             {
-                List<ActivityInfo> loadedData = null;
+                if (!File.Exists(fileName))
+                    continue;
                 
                 // parse as one instance per day
+                List<ActivityInfo> loadedData = null;
                 if (wholeDay)
-                    loadedData = ProcessOneLogInFileAsDays(fileName);
+                    loadedData = ProcessOneLogInFileAsDays(fileName, startTime, endTime);
                 // parse by interval length
                 else
-                    loadedData = ProcessOneLoginFileAsIntervals(fileName, interval);
+                    loadedData = ProcessOneLoginFileAsIntervals(fileName, interval, startTime, endTime);
 
                 list.AddRange(loadedData);
             }
@@ -63,13 +70,16 @@ namespace ServerApp.Parser.Parsers
         /// Parses data from one data file as one instance per day
         /// </summary>
         /// <param name="path">Path ti file</param>
+        /// <param name="endTime">End time of related data</param>
+        /// <param name="startTime">Start time of related data</param>
         /// <returns>List with ActivityInfo instances</returns>
-        private List<ActivityInfo> ProcessOneLogInFileAsDays(string path)
+        private List<ActivityInfo> ProcessOneLogInFileAsDays(string path, DateTime startTime, DateTime endTime)
         {
+            List<ActivityInfo> loginInfo = new List<ActivityInfo>();
+
             if (!File.Exists(path))
-                return null;
+                return loginInfo;
 
-            List<ActivityInfo> loginInfo = new List<ActivityInfo>();
             List<LogInInstance> list = loader.LoadLoginFile(path);
 
             // data for each faculty
@@ -103,6 +113,10 @@ namespace ServerApp.Parser.Parsers
                     lastStartDay = date;
                 }
 
+                // if not in allowed time window -> discard
+                if (list[i].date < startTime || list[i].date > endTime)
+                    continue;
+
                 // aggregate data
                 if (TagInfo.buildingTags.ContainsKey(place))
                 {
@@ -140,13 +154,16 @@ namespace ServerApp.Parser.Parsers
         /// </summary>
         /// <param name="path">Path to file</param>
         /// <param name="interval">Interval length</param>
+        /// <param name="endTime">End time of related data</param>
+        /// <param name="startTime">Start time of related data</param>
         /// <returns>List with ActivityInfo instances</returns>
-        private List<ActivityInfo> ProcessOneLoginFileAsIntervals(string path, int interval)
+        private List<ActivityInfo> ProcessOneLoginFileAsIntervals(string path, int interval, DateTime startTime, DateTime endTime)
         {
+            List<ActivityInfo> loginInfo = new List<ActivityInfo>();
+            
             if (!File.Exists(path))
-                return null;
+                return loginInfo;
 
-            List<ActivityInfo> loignInfo = new List<ActivityInfo>();
             List<LogInInstance> list = loader.LoadLoginFile(path);
 
             // min/max hour taken into account
@@ -190,7 +207,7 @@ namespace ServerApp.Parser.Parsers
                         for (int l = 0; l < TagInfo.buildings.Length; l++)
                         {
                             ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[l], data[k][l], stTime, interval);
-                            loignInfo.Add(dayInfo);
+                            loginInfo.Add(dayInfo);
                         }
 
                         data[k] = new int[TagInfo.buildings.Length];
@@ -198,6 +215,10 @@ namespace ServerApp.Parser.Parsers
                     lastStartTime = date;
                 }
 
+                // if not in allowed time window -> discard
+                if (list[i].date < startTime || list[i].date > endTime)
+                    continue;
+
                 // find index for current instance
                 index = 0;
                 for (int k = 1; k < to.Length; k++)
@@ -243,11 +264,11 @@ namespace ServerApp.Parser.Parsers
                 for (int l = 0; l < TagInfo.buildings.Length; l++)
                 {
                     ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[l], data[k][l], stTime, interval);
-                    loignInfo.Add(dayInfo);
+                    loginInfo.Add(dayInfo);
                 }
             }
 
-            return loignInfo;
+            return loginInfo;
         }
 
     }
diff --git a/Server/ServerApp/Parser/Parsers/TagInfo.cs b/Server/ServerApp/Parser/Parsers/TagInfo.cs
index 85c8fc4..da5006b 100644
--- a/Server/ServerApp/Parser/Parsers/TagInfo.cs
+++ b/Server/ServerApp/Parser/Parsers/TagInfo.cs
@@ -1,9 +1,14 @@
-﻿using System.Collections.Generic;
+﻿//
+// Author: A. Konig
+//
 
-// 30min
+using System.Collections.Generic;
 
 namespace ServerApp.Parser.Parsers
 {
+    /// <summary>
+    /// Class with Tags used in application
+    /// </summary>
     /// <author>Alex Konig</author>
     class TagInfo
     {
diff --git a/Server/ServerApp/Parser/Parsers/WeatherParser.cs b/Server/ServerApp/Parser/Parsers/WeatherParser.cs
index 4d39eda..f8754a1 100644
--- a/Server/ServerApp/Parser/Parsers/WeatherParser.cs
+++ b/Server/ServerApp/Parser/Parsers/WeatherParser.cs
@@ -1,4 +1,8 @@
-﻿using ServerApp.Parser.InputData;
+﻿//
+// Author: A. Konig
+//
+
+using ServerApp.Parser.InputData;
 using ServerApp.Parser.OutputInfo;
 using System;
 using System.Collections.Generic;
@@ -10,18 +14,18 @@ namespace ServerApp.Parser.Parsers
     /// Class parsing weather files into instances of WeatherInfo divided by given time interval
     /// Data parsed from 7am (included) to 18pm (included)
     /// </summary>
-    /// <author>Alex Konig</author>
+    /// <author>A. Konig</author>
     class WeatherParser
     {
 
         /// <summary> Datafile loader  </summary>
-        DataLoader loader;
+        IDataLoader loader;
 
         /// <summary>
         /// Constructor
         /// </summary>
         /// <param name="loader">Datafile loader</param>
-        public WeatherParser(DataLoader loader)
+        public WeatherParser(IDataLoader loader)
         {
             this.loader = loader;
         }
@@ -30,30 +34,33 @@ namespace ServerApp.Parser.Parsers
         /// Parses weather data to WeatherInfo instances
         /// Data parsed from 7am (included) to 18pm (included)
         /// </summary>
-        /// <param name="folder">Folder with weather data files</param>
+        /// <param name="weatherFiles">Paths to files with weather data files</param>
+        /// <param name="endTime">End time of related data</param>
+        /// <param name="startTime">Start time of related data</param>
         /// <param name="wholeDay">Should data be parsed as one instance per day (if true parameter interval will be ignored)</param>
         /// <param name="interval">Time interval to divide days by, minimum is 1h</param>
         /// <returns></returns>
-        public List<WeatherInfo> ParseWeatherData(string folder, bool wholeDay = true, int interval = 1)
+        public List<WeatherInfo> ParseWeatherData(List<string> weatherFiles, DateTime startTime, DateTime endTime, bool wholeDay = true, int interval = 1)
         {
-            if (!Directory.Exists(folder))
-                return null;
-
             List<WeatherInfo> list = new List<WeatherInfo>();
 
+            if (weatherFiles == null || startTime == null || endTime == null || interval <= 0)
+                return list;
+
             // get all files in folder
-            string[] fileEntries = Directory.GetFiles(folder);
-            foreach (string fileName in fileEntries)
+            foreach (string fileName in weatherFiles)
             {
-                List<WeatherInfo> loadedData = null;
-                
+                if (!File.Exists(fileName))
+                    continue;
+
                 // parse as one instance per day
+                List<WeatherInfo> loadedData = null;
                 if (wholeDay)
-                    loadedData = ProcessOneWeatherFileAsDays(fileName);
+                    loadedData = ProcessOneWeatherFileAsDays(fileName, startTime, endTime);
                 // parse according to interval
                 else
                 {
-                    loadedData = ProcessOneWeatherFileAsIntervals(fileName, interval);
+                    loadedData = ProcessOneWeatherFileAsIntervals(fileName, interval, startTime, endTime);
                 }
 
                 list.AddRange(loadedData);
@@ -66,13 +73,16 @@ namespace ServerApp.Parser.Parsers
         /// Parses data from one data file as one instance per day
         /// </summary>
         /// <param name="path">Path ti file</param>
+        /// <param name="endTime">End time of related data</param>
+        /// <param name="startTime">Start time of related data</param>
         /// <returns>List with WeatherInfo instances</returns>
-        private List<WeatherInfo> ProcessOneWeatherFileAsDays(string path)
+        private List<WeatherInfo> ProcessOneWeatherFileAsDays(string path, DateTime startTime, DateTime endTime)
         {
+            List<WeatherInfo> weatherInfo = new List<WeatherInfo>();
+
             if (!File.Exists(path))
-                return null;
+                return weatherInfo;
 
-            List<WeatherInfo> weatherInfo = new List<WeatherInfo>();
             List<WeatherInstance> list = loader.LoadWeatherFile(path);
 
             // array with data [temp, rain, wind, lum]
@@ -105,6 +115,10 @@ namespace ServerApp.Parser.Parsers
                     weatherValues = 0;
                 }
 
+                // if not in allowed time window -> discard
+                if (list[i].dateTime < startTime|| list[i].dateTime > endTime)
+                    continue;
+
                 // aggregate data
                 recordedAmount[0] += list[i].temp;
                 recordedAmount[1] += list[i].rain;
@@ -128,13 +142,16 @@ namespace ServerApp.Parser.Parsers
         /// </summary>
         /// <param name="path">Path to file</param>
         /// <param name="interval">Interval length</param>
+        /// <param name="endTime">End time of related data</param>
+        /// <param name="startTime">Start time of related data</param>
         /// <returns>List with ActivityInfo instances</returns>
-        private List<WeatherInfo> ProcessOneWeatherFileAsIntervals(string path, int interval)
+        private List<WeatherInfo> ProcessOneWeatherFileAsIntervals(string path, int interval, DateTime startTime, DateTime endTime)
         {
+            List<WeatherInfo> weatherInfo = new List<WeatherInfo>();
+
             if (!File.Exists(path))
-                return null;
+                return weatherInfo;
 
-            List<WeatherInfo> loignInfo = new List<WeatherInfo>();
             List<WeatherInstance> list = loader.LoadWeatherFile(path);
 
             // min/max hour taken into account
@@ -184,7 +201,7 @@ namespace ServerApp.Parser.Parsers
 
                         WeatherInfo intervalInfo = new WeatherInfo(stTime, data[k][0] / count[k], (int)((rainval / raincount) * 100), data[k][2] / count[k], data[k][3] / count[k], interval);
                         if (count[k] != 0)
-                            loignInfo.Add(intervalInfo);
+                            weatherInfo.Add(intervalInfo);
 
                     }
 
@@ -194,6 +211,10 @@ namespace ServerApp.Parser.Parsers
                         data[l] = new double[4];
                 }
 
+                // if not in allowed time window -> discard
+                if (list[i].dateTime < startTime || list[i].dateTime > endTime)
+                    continue;
+
                 // find index for current instance
                 index = 0;
                 for (int k = 1; k < to.Length; k++)
@@ -228,10 +249,10 @@ namespace ServerApp.Parser.Parsers
 
                 WeatherInfo intervalInfo = new WeatherInfo(stTime, data[k][0] / count[k], (int)((rainval / raincount) * 100), data[k][2] / count[k], data[k][3] / count[k], interval);
                 if (count[k] != 0)
-                    loignInfo.Add(intervalInfo);
+                    weatherInfo.Add(intervalInfo);
             }
 
-            return loignInfo;
+            return weatherInfo;
         }
     }
 
diff --git a/Server/ServerApp/Program.cs b/Server/ServerApp/Program.cs
index 61a67ce..745b356 100644
--- a/Server/ServerApp/Program.cs
+++ b/Server/ServerApp/Program.cs
@@ -3,6 +3,7 @@ using ServerApp.DataDownload;
 using ServerApp.Parser.Parsers;
 using ServerApp.Predictor;
 using ServerApp.User;
+using ServerApp.WeatherPredictionParser;
 using System;
 using System.Collections.Generic;
 using System.IO;
@@ -30,10 +31,7 @@ namespace ServerApp
         static void Main(string[] args)
         {
 
-			JsonParser p = new JsonParser(null);
-			p.ParsePrediction();
-
-			/*
+			// SETUP FOLDERS
 
 			Config config = FillConfigInfo(args);
 			if (config == null)
@@ -42,15 +40,11 @@ namespace ServerApp
 				return;
 			}
 
+			/* 
 			//create a thread for commands accepting:
 			Thread inputThread = new Thread(CommandsAcceptor.AcceptCommand);
 			inputThread.Start();
-
-
-
-			//DataParser p = new DataParser("data/");
-			//p.Parse();
-
+			 */
 
 			//test scenario -data download:
 			DataDownloader dd = new DataDownloader(config.DataRootDir, config.DataWebsite, config.DownloadedFilesNaming);
@@ -60,8 +54,6 @@ namespace ServerApp
 			savedFiles.AddRange(dd.DownloadData(DataType.STROJE, DataFormat.CSV, new Date(1, 2017), new Date(12, 2020)));
 			savedFiles.AddRange(dd.DownloadData(DataType.POCASI, DataFormat.CSV, new Date(1, 2017), new Date(12, 2020)));
 
-
-
 			Console.WriteLine("Saved files: ");
 			foreach (string s in savedFiles)
 			{
@@ -74,6 +66,8 @@ namespace ServerApp
 				Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
 			}
 
+			/*
+			
 			List<string> retrievedData = dd.GetData(dd.DataSubDirectories[DataType.JIS], new Date(10, 2019), new Date(12, 2020));
 			Console.WriteLine("Retrieved data: ");
 			foreach (string s in retrievedData)
@@ -82,6 +76,19 @@ namespace ServerApp
 			}
 			*/
 
+			// PARSE DATA
+
+
+			JsonParser jsonP = new JsonParser(null);
+			jsonP.ParsePrediction();
+
+			// TODO nastavit čas
+			DataParser p = new DataParser(dd);
+			DateTime startT = new DateTime(2019, 10, 5);
+			DateTime endT = new DateTime(2020, 6, 30);
+			p.Parse(startT, endT, wholeDay: false, interval: 3);
+
+
 			// test - connection:
 			//ConnectionListener cl = new ConnectionListener(int.Parse(args[0])/*8000*//*int.Parse(config.Port)*/);
 			//cl.StartListening();
diff --git a/Server/ServerApp/ServerApp.csproj b/Server/ServerApp/ServerApp.csproj
index 20bcfd6..1ca848d 100644
--- a/Server/ServerApp/ServerApp.csproj
+++ b/Server/ServerApp/ServerApp.csproj
@@ -16,6 +16,21 @@
     <Deterministic>true</Deterministic>
     <NuGetPackageImportStamp>
     </NuGetPackageImportStamp>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -146,7 +161,7 @@
     <Compile Include="DataDownload\DataDownloader.cs" />
     <Compile Include="DataDownload\Date.cs" />
     <Compile Include="Parser\InputData\CsvDataLoader.cs" />
-    <Compile Include="Parser\InputData\DataLoader.cs" />
+    <Compile Include="Parser\InputData\IDataLoader.cs" />
     <Compile Include="Parser\InputData\JisInstance.cs" />
     <Compile Include="Parser\InputData\LogInInstance.cs" />
     <Compile Include="Parser\InputData\WeatherInstance.cs" />
@@ -154,8 +169,9 @@
     <Compile Include="Parser\OutputInfo\WeatherConditions.cs" />
     <Compile Include="Parser\OutputInfo\WeatherInfo.cs" />
     <Compile Include="Parser\Parsers\DataParser.cs" />
+    <Compile Include="Parser\Parsers\IDataParser.cs" />
     <Compile Include="Parser\Parsers\JisParser.cs" />
-    <Compile Include="Parser\Parsers\JsonParser.cs" />
+    <Compile Include="WeatherPredictionParser\JsonParser.cs" />
     <Compile Include="Parser\Parsers\LogInParser.cs" />
     <Compile Include="Parser\Parsers\TagInfo.cs" />
     <Compile Include="Parser\Parsers\WeatherParser.cs" />
@@ -208,6 +224,18 @@
   <ItemGroup>
     <Folder Include="data\auto\" />
   </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include=".NETFramework,Version=v4.7.2">
+      <Visible>False</Visible>
+      <ProductName>Microsoft .NET Framework 4.7.2 %28x86 and x64%29</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
     <PropertyGroup>
diff --git a/Server/ServerApp/WeatherPredictionParser/IJsonParser.cs b/Server/ServerApp/WeatherPredictionParser/IJsonParser.cs
new file mode 100644
index 0000000..31c8058
--- /dev/null
+++ b/Server/ServerApp/WeatherPredictionParser/IJsonParser.cs
@@ -0,0 +1,32 @@
+﻿//
+// Author: A. Konig
+//
+
+using ServerApp.Parser.OutputInfo;
+using System.Collections.Generic;
+
+namespace ServerApp.WeatherPredictionParser
+{
+    /// <summary>
+    /// Abstract class that every Json parser should inherit from
+    /// </summary>
+    abstract class IJsonParser
+    {
+
+        /// <summary> Current weather </summary>
+        WeatherInfo current;
+        public WeatherInfo Current { get => current; }
+
+        /// <summary> Prediction for today, tommorrow and day after tommorrow </summary>
+        List<WeatherInfo> predictions;
+        public List<WeatherInfo> Predictions { get => predictions; set => predictions = value; }
+
+        /// <summary>
+        /// Parse weather prediction
+        /// Results is in attributes current for current weather and pred for weather prediction for today, tommorrow and day after tommorrow
+        /// </summary>
+        abstract public void ParsePrediction();
+
+    }
+
+}
diff --git a/Server/ServerApp/WeatherPredictionParser/JsonParser.cs b/Server/ServerApp/WeatherPredictionParser/JsonParser.cs
new file mode 100644
index 0000000..e9a7c42
--- /dev/null
+++ b/Server/ServerApp/WeatherPredictionParser/JsonParser.cs
@@ -0,0 +1,406 @@
+﻿//
+// Author: A. Konig
+//
+
+using ServerApp.DataDownload;
+using ServerApp.Parser.OutputInfo;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Net;
+using System.Text.Json;
+using static System.Text.Json.JsonElement;
+
+namespace ServerApp.WeatherPredictionParser
+{
+    /// <summary>
+    /// Class representing a parser for json prediction data
+    /// </summary>
+    /// <author>A. Konig</author>
+    class JsonParser : IJsonParser
+    {
+        /// <summary> Current weather </summary>
+        WeatherInfo current;
+        public new WeatherInfo Current { get => current; }
+        /// <summary> Prediction for today, tommorrow and day after tommorrow </summary>
+        List<WeatherInfo> predictions;
+        public new List<WeatherInfo> Predictions { get => predictions; set => predictions = value; }
+
+        /// <summary> Data loader </summary>
+        DataDownloader loader;
+        /// <summary> Currently parsed day </summary>
+        DateTime currParsedDay;
+        /// <summary> Sunrise time of currently parsed day </summary>
+        DateTime sunriseTime;
+        /// <summary> Sunset time of currently parsed day </summary>
+        DateTime sunsetTime;
+
+
+        /// <summary>
+        /// Constructor
+        /// </summary>
+        /// <param name="loader"></param>
+        public JsonParser(DataDownloader loader)
+        {
+            this.loader = loader;
+        }
+
+        /// <summary>
+        /// Parse weather prediction
+        /// Results is in attributes current for current weather and pred for weather prediction for today, tommorrow and day after tommorrow
+        /// </summary>
+        override public void ParsePrediction()
+        {
+            // TODO ask DataDownloader for download said file and return path to it
+            
+            // get file
+            string file = DownloadWeatherPrediction();
+            DateTime now = DateTime.Now;
+            Console.WriteLine(File.Exists(file));
+
+            current = new WeatherInfo();
+            predictions = new List<WeatherInfo>();
+
+            if (!File.Exists(file))
+                return;
+
+            // read file
+            string data = File.ReadAllText(file);
+
+            // parse
+            JsonDocument doc = JsonDocument.Parse(data);
+            JsonElement root = doc.RootElement;
+            var weatherP = root.EnumerateObject();
+
+            while (weatherP.MoveNext())
+            {
+                string name = weatherP.Current.Name;
+                Console.WriteLine(name);
+
+                switch (name)
+                {
+                    // current weather
+                    case "current_condition":
+                        {
+                            ArrayEnumerator currentWeather = weatherP.Current.Value.EnumerateArray();
+                            current = ParseCurrentWeather(currentWeather);
+
+                            break;
+
+                        }
+                    // weather prediction
+                    case "weather":
+                        {
+                            ArrayEnumerator weather = weatherP.Current.Value.EnumerateArray();
+                            ParseWeatherPredict(weather);
+
+                            break;
+                        }
+                }
+            }
+
+            // sunrise + sunset into data
+            EncompassSunRiseSetTimes();
+
+            TestConsoleOutput();
+        }
+
+        /// <summary>
+        /// Test console output
+        /// </summary>
+        private void TestConsoleOutput()
+        {
+            Console.WriteLine(current);
+            foreach (WeatherInfo w in predictions)
+                Console.WriteLine(w);
+        }
+
+        // TODO move to data loader
+        /// <summary>
+        /// Downloads json file
+        /// </summary>
+        /// <returns> Path to file </returns>
+        private string DownloadWeatherPrediction()
+        {
+            DateTime now = DateTime.Now;
+            WebClient webClient = new WebClient();
+            webClient.DownloadFile("http://wttr.in/Plzen,czechia?format=j1", $"data/{now.Year}{now.Month}{now.Day}.json");
+
+            return $"data/{now.Year}{now.Month}{now.Day}.json";
+        }
+
+        /// <summary>
+        /// Change data in a way that they now reflect sunrise and sunset times
+        /// If current time under sunrise or over sunset -> WeatherConditions is Dark
+        /// If prediction time is under sunrise or over sunset and more than half of the interval is under/over said time -> WeatherCondition is Dark
+        /// </summary>
+        private void EncompassSunRiseSetTimes()
+        {
+            // change current weather
+            if ((current.startTime.TimeOfDay > sunsetTime.TimeOfDay) || (current.startTime.TimeOfDay < sunriseTime.TimeOfDay))
+                current.condition = WeatherConditions.Dark;
+
+            // change prediction
+            for (int i = 0; i < predictions.Count - 1; i++)
+            {
+                WeatherInfo w = predictions[i];
+                WeatherInfo wNext = predictions[i + 1];
+
+                // if wNext time < than w time then it is prediction from the next day -> add 24 to correctly calculate timespan
+                int timespan = wNext.startTime.Hour - w.startTime.Hour;
+                if (wNext.startTime.Hour < w.startTime.Hour)
+                    timespan = (wNext.startTime.Hour+24) - w.startTime.Hour;
+                
+                w.intervalLength = timespan;
+
+                // if start under sunset
+                if (w.startTime.TimeOfDay > sunsetTime.TimeOfDay)
+                    w.condition = WeatherConditions.Dark;
+
+                // if start under sunrise
+                if (w.startTime.TimeOfDay < sunriseTime.TimeOfDay)
+                {
+                    double howMuch = ((sunriseTime.Hour * 60 + sunriseTime.Minute) - (w.startTime.Hour * 60 + w.startTime.Minute)) / 60.0;
+
+                    if (howMuch >= timespan / 2.0)
+                        w.condition = WeatherConditions.Dark;
+                }
+
+                // if start under sunrise
+                TimeSpan endTime = new TimeSpan(w.startTime.TimeOfDay.Hours + timespan, w.startTime.TimeOfDay.Minutes, 0);
+                if (endTime > sunsetTime.TimeOfDay)
+                {
+                    double howMuch = ((endTime.Hours * 60 + endTime.Minutes) - (sunsetTime.Hour * 60 + sunsetTime.Minute)) / 60.0;
+
+                    if (howMuch >= timespan / 2.0)
+                        w.condition = WeatherConditions.Dark;
+                }
+            }
+
+            // last prediction
+            WeatherInfo wLast = predictions[predictions.Count - 1];
+            TimeSpan endTimeW = new TimeSpan(24, 0, 0);
+            int timespanLast = endTimeW.Hours - wLast.startTime.Hour;
+            wLast.intervalLength = timespanLast;
+
+            // if start under sunset
+            if (wLast.startTime.TimeOfDay > sunsetTime.TimeOfDay)
+                wLast.condition = WeatherConditions.Dark;
+
+            // if start under sunrise
+            if (wLast.startTime.TimeOfDay < sunriseTime.TimeOfDay)
+            {
+                double howMuch = ((sunriseTime.Hour * 60 + sunriseTime.Minute) - (wLast.startTime.Hour * 60 + wLast.startTime.Minute)) / 60.0;
+
+                if (howMuch >= timespanLast / 2.0)
+                    wLast.condition = WeatherConditions.Dark;
+            }
+
+            // if start under sunrise
+            if (endTimeW > sunsetTime.TimeOfDay)
+            {
+                double howMuch = ((endTimeW.Hours * 60 + endTimeW.Minutes) - (sunsetTime.Hour * 60 + sunsetTime.Minute)) / 60.0;
+
+                if (howMuch >= timespanLast / 2.0)
+                    wLast.condition = WeatherConditions.Dark;
+            }
+        }
+
+        /// <summary>
+        /// Parse weather prediction
+        /// </summary>
+        /// <param name="weather"> ArrayEnumerator of weather predictions </param>
+        private void ParseWeatherPredict(ArrayEnumerator weather)
+        {
+            while (weather.MoveNext())
+            {
+                // prediction for one day
+                var obj = weather.Current.EnumerateObject();
+
+                while (obj.MoveNext())
+                {
+                    switch (obj.Current.Name)
+                    {
+                        case "date":
+                            {
+                                DateTime.TryParseExact(obj.Current.Value.GetString(), "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out currParsedDay);
+                                break;
+                            }
+                        // hourly predictions
+                        case "hourly":
+                            {
+                                ParseHourly(obj.Current.Value.EnumerateArray());
+                                break;
+                            }
+                        // sunset / sunrise hours
+                        case "astronomy":
+                            {
+                                ParseAstronomy(obj.Current.Value.EnumerateArray());
+                                break;
+                            }
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// Parse sunrise and sunset times
+        /// </summary>
+        /// <param name="astronomy"> Astronomy array enumerator </param>
+        private void ParseAstronomy(ArrayEnumerator astronomy)
+        {
+            while (astronomy.MoveNext())
+            {
+                var astrInfo = astronomy.Current.EnumerateObject();
+                
+                while (astrInfo.MoveNext())
+                {
+                    switch (astrInfo.Current.Name)
+                    {
+                        case "sunrise":
+                            {
+                                DateTime.TryParseExact(astrInfo.Current.Value.GetString(), "hh:mm tt", CultureInfo.InvariantCulture, DateTimeStyles.None, out sunriseTime);
+                                Console.WriteLine("\t sunrise time : " + sunriseTime + " " + astrInfo.Current.Value.GetString());
+                                break;
+                            }
+                        case "sunset":
+                            {
+                                DateTime.TryParseExact(astrInfo.Current.Value.GetString(), "hh:mm tt", CultureInfo.InvariantCulture, DateTimeStyles.None, out sunsetTime);
+                                Console.WriteLine("\t sunset time : " + sunsetTime + " " + astrInfo.Current.Value.GetString());
+                                break;
+                            }
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// Parse hourly predictions
+        /// </summary>
+        /// <param name="hourly">Enumerated array of hourly predictions</param>
+        private void ParseHourly(ArrayEnumerator hourly)
+        {
+            while (hourly.MoveNext())
+            {
+                // one hourly prediction
+                var oneH = hourly.Current.EnumerateObject();
+                WeatherInfo weather = new WeatherInfo();
+
+                while (oneH.MoveNext())
+                {
+                    switch (oneH.Current.Name)
+                    {
+                        case "FeelsLikeC":
+                            {
+                                Double.TryParse(oneH.Current.Value.GetString(), out weather.temp);
+                                break;
+                            }
+                        case "cloudcover":
+                            {
+                                int cloudCover;
+                                Int32.TryParse(oneH.Current.Value.GetString(), out cloudCover);
+                                weather.condition = ValueToConditions.CloudCoverToConditions(cloudCover);
+                                break;
+                            }
+                        // take into account highest value from "chanceofrain" and "chaceofsnow"
+                        case "chanceofrain":
+                            {
+                                int rain;
+                                Int32.TryParse(oneH.Current.Value.GetString(), out rain);
+                                weather.rain = rain > weather.rain ? rain : weather.rain;
+                                break;
+                            }
+                        case "chanceofsnow":
+                            {
+                                int snow;
+                                Int32.TryParse(oneH.Current.Value.GetString(), out snow);
+                                weather.rain = snow > weather.rain ? snow : weather.rain;
+                                break;
+                            }
+                        // wind kmph has to be translated to mps
+                        case "WindGustKmph":
+                            {
+                                double windkmh;
+                                Double.TryParse(oneH.Current.Value.GetString(), out windkmh);
+                                weather.wind= windkmh * 1000 / (60.0*60.0);
+                                break;
+                            }
+                        case "time":
+                            {
+                                int h;
+                                Int32.TryParse(oneH.Current.Value.GetString(), out h);
+                                h /= 100;
+                                DateTime time = new DateTime(currParsedDay.Year, currParsedDay.Month, currParsedDay.Day, h, 0, 0);
+                                weather.startTime = time;
+                                break;
+                            }
+                    }
+                }
+
+                // Console.WriteLine(weather.ToString());
+                predictions.Add(weather);
+
+            }
+
+        }
+
+        /// <summary>
+        /// Parse current weather
+        /// </summary>
+        /// <param name="currentWeather">Enumerated hour of weather data</param>
+        /// <returns>WeatherInfo with current weather</returns>
+        private WeatherInfo ParseCurrentWeather(ArrayEnumerator currentWeather)
+        {
+            WeatherInfo res = new WeatherInfo();
+            //res.current = true;
+
+            while (currentWeather.MoveNext())
+            {
+                var obj = currentWeather.Current.EnumerateObject();
+
+                while (obj.MoveNext())
+                {
+                    switch (obj.Current.Name)
+                    {
+                        case "localObsDateTime":
+                            {
+                                DateTime.TryParse(obj.Current.Value.GetString(), out res.startTime);
+                                break;
+                            }
+                        case "FeelsLikeC":
+                            {
+                                Double.TryParse(obj.Current.Value.GetString(), out res.temp);
+                                break;
+                            }
+                        case "cloudcover":
+                            {
+                                int cloudCover;
+                                Int32.TryParse(obj.Current.Value.GetString(), out cloudCover);
+                                res.condition = ValueToConditions.CloudCoverToConditions(cloudCover);
+                                break;
+                            }
+                        case "precipMM":
+                            {
+                                double rainMM;
+                                Double.TryParse(obj.Current.Value.GetString(), out rainMM);
+                                res.rain = rainMM > 0 ? 100 : 0;
+                                break;
+                            }
+                        case "windspeedKmph":
+                            {
+                                double wind;
+                                Double.TryParse(obj.Current.Value.GetString(), out wind);
+                                res.wind = wind * 1000 / (60.0 * 60.0);
+                                break;
+                            }
+                    }
+                }
+
+            }
+
+            return res;
+        }
+
+    }
+}
