示例#1
0
        static void Main(string[] args)
        {
            var controller = new ClimateController(new ClimateMode(23, 10));

            controller.Add("colder", new ClimateMode(20, 5));

            Console.WriteLine(controller.CurrentState);

            while (true)
            {
                if (Console.ReadKey().KeyChar == 'q')
                {
                    break;
                }

                Console.WriteLine(controller.CurrentState);
            }

            Console.WriteLine("Setting t = 20, h = 5");
            controller.ChooseMode("colder");

            while (true)
            {
                if (Console.ReadKey().KeyChar == 'q')
                {
                    break;
                }

                Console.WriteLine(controller.CurrentState);
            }
        }
示例#2
0
        public void ClimateController_IClimateSources_are_of_correct_type()
        {
            ConfigurationBuilder builder = new ConfigurationBuilder();

            builder.AddEnvironmentVariables();

            IConfigurationRoot      Configuration = builder.Build();
            IOptions <AppKeyConfig> options       = Options.Create(new AppKeyConfig()
            {
                UserName            = Configuration["NETATMO_USERNAME"],
                Password            = Configuration["NETATMO_PASSWORD"],
                NetatmoClientId     = Configuration["NETATMO_CLIENTID"],
                NetatmoClientSecret = Configuration["NETATMO_CLIENTSECRET"],
                NibeClientId        = Configuration["NIBE_ID"],
                NibeClientSecret    = Configuration["NIBE_SECRET"],
                NibeRedirectURI     = Configuration["NIBE_REDIRECTURL"],
                NibeHost            = Configuration["NIBE_HOST"],
                NetatmoHost         = Configuration["NETATMO_HOST"],
                BuildVersion        = Configuration["BUILD_VERSION"]
            });

            ConcurrentDictionary <string, IClimateSource> sources = new ConcurrentDictionary <string, IClimateSource>();
            NibeUnit nibeUnit = new NibeUnit();

            sources["Nibe"]    = nibeUnit;
            sources["Netatmo"] = new NetatmoUnit();
            LoggerFactory loggerFactory = new LoggerFactory();

            loggerFactory.AddConsole();
            ILogger <ClimateController> logger            = new Logger <ClimateController>(loggerFactory);
            ClimateController           climateController = new ClimateController(options, sources, logger);

            Assert.IsType <NetatmoUnit>(climateController.netatmo);
            Assert.IsType <NibeUnit>(climateController.nibe);
        }
示例#3
0
        public ClimateControllerTests()
        {
            ConfigurationBuilder builder = new ConfigurationBuilder();

            builder.AddEnvironmentVariables();

            Configuration = builder.Build();
            IOptions <AppKeyConfig> options = Options.Create(new AppKeyConfig()
            {
                UserName            = Configuration["NETATMO_USERNAME"],
                Password            = Configuration["NETATMO_PASSWORD"],
                NetatmoClientId     = Configuration["NETATMO_CLIENTID"],
                NetatmoClientSecret = Configuration["NETATMO_CLIENTSECRET"],
                NibeClientId        = Configuration["NIBE_ID"],
                NibeClientSecret    = Configuration["NIBE_SECRET"],
                NibeRedirectURI     = Configuration["NIBE_REDIRECTURL"],
                NibeHost            = Configuration["NIBE_HOST"],
                NetatmoHost         = Configuration["NETATMO_HOST"],
                BuildVersion        = Configuration["BUILD_VERSION"]
            });
            ConcurrentDictionary <string, IClimateSource> sources = new ConcurrentDictionary <string, IClimateSource>();

            sources["Nibe"]    = nibeMock.Object;
            sources["Netatmo"] = netatmoMock.Object;
            LoggerFactory loggerFactory = new LoggerFactory();

            loggerFactory.AddConsole();
            ILogger <ClimateController> logger = new Logger <ClimateController>(loggerFactory);

            _climateController = new ClimateController(options, sources, logger);
        }
示例#4
0
        public void GetRecommendation_InvalidCityCode()
        {
            var controller             = new ClimateController();
            IHttpActionResult response = controller.Get("123");
            var contentResult          = response as OkNegotiatedContentResult <RecommendationResponse>;

            Assert.IsNull(contentResult);
        }
示例#5
0
        public void GetRecommendation_ShouldBeOK()
        {
            var controller    = new ClimateController();
            var response      = controller.Get("2886242");
            var contentResult = response as OkNegotiatedContentResult <RecommendationResponse>;

            Assert.IsNotNull(contentResult);
            Assert.IsNotNull(contentResult.Content);
        }
示例#6
0
        public void GetRecommendation_MockData_Valid()
        {
            var controller    = new ClimateController();
            var response      = controller.Get("101");
            var contentResult = response as OkNegotiatedContentResult <RecommendationResponse>;

            Assert.IsNotNull(contentResult);
            Assert.IsNotNull(contentResult.Content);
            Assert.AreEqual(contentResult.Content.Temparature, 22);
        }
示例#7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="writer"></param>
        public void WriteXml(XmlWriter writer)
        {
            XDocument doc = new XDocument();

            doc.AddFirst(new XElement("Project",
                                      new XAttribute("CreatedBy", "Unknown Author"),
                                      new XAttribute("CreationDate", this.CreatedDate.ToString("dd/MM/yyyy")),
                                      new XAttribute("ContactDetails", "Unknown Contact Details"),
                                      new XAttribute("ModifiedBy", "How Leaky"),
                                      new XAttribute("minx", 0.0000),
                                      new XAttribute("maxx", 0.0000),
                                      new XAttribute("miny", 0.0000),
                                      new XAttribute("maxy", 0.000)));

            XElement ModelElement = new XElement("ClimateData");

            doc.Root.Add(ModelElement);

            foreach (InputModel im in this.InputDataModels.Where(x => x.GetType() == typeof(ClimateInputModel)))
            {
                XElement temp = new XElement("DataFile", new XAttribute("href", im.FileName), new XAttribute("text", im.Text == null ? "" : im.Text), new XAttribute("Description", im.Description == null ? "" : im.Description));
                ModelElement.Add(temp);
            }

            ModelElement = new XElement("SoilTemplates");
            doc.Root.Add(ModelElement);
            foreach (InputModel im in this.InputDataModels.Where(x => x.GetType() == typeof(SoilInputModel)))
            {
                ModelElement.Add(new XElement("SoilType",
                                              new XAttribute("href", im.FileName),
                                              new XAttribute("text", im.Text == null ? "" : im.Text),
                                              new XAttribute("Description", im.Description == null ? "" : im.Description)));
            }

            ModelElement = new XElement("CropTemplates");
            doc.Root.Add(ModelElement);
            foreach (InputModel im in this.InputDataModels.Where(x => x.GetType().BaseType == typeof(VegInputModel)))
            {
                ModelElement.Add(new XElement("VegetationType",
                                              new XAttribute("href", im.FileName),
                                              new XAttribute("text", im.Text == null ? "" : im.Text),
                                              new XAttribute("Description", im.Description == null ? "" : im.Description),
                                              new XElement("ModelType", new XAttribute("index", im.GetType() == typeof(LAIVegInputModel) ? 1 : 0))
                                              ));
            }

            ModelElement = new XElement("TillageTemplates");
            doc.Root.Add(ModelElement);
            foreach (InputModel im in this.InputDataModels.Where(x => x.GetType() == typeof(TillageInputModel)))
            {
                ModelElement.Add(new XElement("TillageType", new XAttribute("href", im.FileName), new XAttribute("text", im.Text == null ? "" : im.Text), new XAttribute("Description", im.Description == null ? "" : im.Description)));
            }

            ModelElement = new XElement("IrrigationTemplates");
            doc.Root.Add(ModelElement);
            foreach (InputModel im in this.InputDataModels.Where(x => x.GetType() == typeof(IrrigationInputModel)))
            {
                ModelElement.Add(new XElement("IrrigationType", new XAttribute("href", im.FileName), new XAttribute("text", im.Text == null ? "" : im.Text), new XAttribute("Description", im.Description == null ? "" : im.Description)));
            }

            ModelElement = new XElement("PesticideTemplates");
            doc.Root.Add(ModelElement);
            foreach (InputModel im in this.InputDataModels.Where(x => x.GetType() == typeof(PesticideInputModel)))
            {
                ModelElement.Add(new XElement("PesticideType", new XAttribute("href", im.FileName), new XAttribute("text", im.Text == null ? "" : im.Text), new XAttribute("Description", im.Description == null ? "" : im.Description)));
            }

            ModelElement = new XElement("PhosphorusTemplates");
            doc.Root.Add(ModelElement);
            foreach (InputModel im in this.InputDataModels.Where(x => x.GetType() == typeof(PhosphorusInputModel)))
            {
                ModelElement.Add(new XElement("SoilType", new XAttribute("href", im.FileName), new XAttribute("text", im.Text == null ? "" : im.Text), new XAttribute("Description", im.Description == null ? "" : im.Description)));
            }

            ModelElement = new XElement("NitratesTemplates");
            doc.Root.Add(ModelElement);
            foreach (InputModel im in this.InputDataModels.Where(x => x.GetType() == typeof(NitrateInputModel)))
            {
                ModelElement.Add(new XElement("NitratesType", new XAttribute("href", im.FileName), new XAttribute("text", im.Text == null ? "" : im.Text), new XAttribute("Description", im.Description == null ? "" : im.Description)));
            }

            ModelElement = new XElement("SolutesTemplates");
            doc.Root.Add(ModelElement);
            foreach (InputModel im in this.InputDataModels.Where(x => x.GetType() == typeof(SolutesInputModel)))
            {
                ModelElement.Add(new XElement("SolutesType", new XAttribute("href", im.FileName), new XAttribute("text", im.Text == null ? "" : im.Text), new XAttribute("Description", im.Description == null ? "" : im.Description)));
            }


            ModelElement = new XElement("Simulations");
            doc.Root.Add(ModelElement);
            int count = 1;

            foreach (Simulation sim in this.Simulations)
            {
                XElement simElement = new XElement("SimulationObject", new XAttribute("Active", true), new XAttribute("ID", count));
                ModelElement.Add(simElement);
                count++;

                //Add the climate
                ClimateController c = (ClimateController)sim.ClimateController;
                XElement          ClimateElement = new XElement("ptrStation", new XAttribute("href", c.GetInputModel().FileName));
                simElement.Add(ClimateElement);
                for (int i = 0; i < c.InputModel.Overrides.Count; i++)
                {
                    if (c.InputModel.Overrides.Keys.ElementAt(i).ToString() == "EvaporationInputOptions")
                    {
                        ClimateElement.Add(new XElement(c.InputModel.Overrides.Keys.ElementAt(i).ToString(),
                                                        new XAttribute("index", c.InputModel.Overrides.Values.ElementAt(i)),
                                                        new XAttribute("text", "Use EPan")));
                    }
                    else
                    {
                        ClimateElement.Add(new XElement(c.InputModel.Overrides.Keys.ElementAt(i).ToString(), c.InputModel.Overrides.Values.ElementAt(i)));
                    }
                }
                //Add the soil
                XElement SoilElement = new XElement("ptrSoilType", new XAttribute("href", sim.SoilController.GetInputModel().FileName));
                simElement.Add(SoilElement);
                for (int i = 0; i < sim.SoilController.InputModel.Overrides.Count; i++)
                {
                    SoilElement.Add(new XElement("OverrideParameter",
                                                 new XAttribute("Keyword", sim.SoilController.InputModel.Overrides.Keys.ElementAt(i)),
                                                 new XAttribute("Active", "true")));
                }

                //Add the crops
                int cropIndex = 1;
                foreach (HLController hlo in sim.VegetationController.ChildControllers)
                {
                    XElement CropElement = new XElement("ptrVegeOption" + cropIndex.ToString(), new XAttribute("href", hlo.GetInputModel().FileName));
                    simElement.Add(CropElement);
                    for (int i = 0; i < hlo.GetInputModel().Overrides.Count; i++)
                    {
                        CropElement.Add(new XElement("OverrideParameter",
                                                     new XAttribute("Keyword", hlo.GetInputModel().Overrides.Values.ElementAt(i)),
                                                     new XAttribute("Active", "true")));
                    }

                    cropIndex++;
                }

                //Add the tillage
                int tillageIndex = 1;
                if (sim.TillageController != null)
                {
                    foreach (HLController hlo in sim.TillageController.ChildControllers)
                    {
                        XElement tillageElement = new XElement("ptrTillageOption" + tillageIndex.ToString(), new XAttribute("href", hlo.GetInputModel().FileName));
                        simElement.Add(tillageElement);
                        for (int i = 0; i < hlo.GetInputModel().Overrides.Count; i++)
                        {
                            tillageElement.Add(new XElement("OverrideParameter",
                                                            new XAttribute("Keyword", hlo.GetInputModel().Overrides.Values.ElementAt(i)),
                                                            new XAttribute("Active", "true")));
                        }

                        tillageIndex++;
                    }
                }

                //Add the pest
                int pestIndex = 1;
                if (sim.PesticideController != null)
                {
                    foreach (HLController hlo in sim.PesticideController.ChildControllers)
                    {
                        XElement pestElement = new XElement("ptrPestOption" + pestIndex.ToString(), new XAttribute("href", hlo.GetInputModel().FileName));
                        simElement.Add(pestElement);
                        for (int i = 0; i < hlo.GetInputModel().Overrides.Count; i++)
                        {
                            pestElement.Add(new XElement("OverrideParameter",
                                                         new XAttribute("Keyword", hlo.GetInputModel().Overrides.Values.ElementAt(i)),
                                                         new XAttribute("Active", "true")));
                        }

                        pestIndex++;
                    }
                }

                if (sim.PhosphorusController != null)
                {
                    XElement PhosphorusElement = new XElement("ptrPhosphorus", new XAttribute("href", sim.PhosphorusController.GetInputModel().FileName));
                    simElement.Add(PhosphorusElement);
                    for (int i = 0; i < sim.PhosphorusController.InputModel.Overrides.Count; i++)
                    {
                        PhosphorusElement.Add(new XElement("OverrideParameter",
                                                           new XAttribute("Keyword", sim.PhosphorusController.InputModel.Overrides.Keys.ElementAt(i)),
                                                           new XAttribute("Active", "true")));
                    }
                }

                if (sim.IrrigationController != null)
                {
                    XElement IrrigationElement = new XElement("ptrIrrigation", new XAttribute("href", sim.IrrigationController.GetInputModel().FileName));
                    simElement.Add(IrrigationElement);
                    for (int i = 0; i < sim.IrrigationController.InputModel.Overrides.Count; i++)
                    {
                        IrrigationElement.Add(new XElement("OverrideParameter",
                                                           new XAttribute("Keyword", sim.IrrigationController.InputModel.Overrides.Keys.ElementAt(i)),
                                                           new XAttribute("Active", "true")));
                    }
                }

                if (sim.NitrateController != null)
                {
                    XElement NitrateElement = new XElement("ptrNitrate", new XAttribute("href", sim.NitrateController.GetInputModel().FileName));
                    simElement.Add(NitrateElement);
                    for (int i = 0; i < sim.NitrateController.InputModel.Overrides.Count; i++)
                    {
                        NitrateElement.Add(new XElement("OverrideParameter",
                                                        new XAttribute("Keyword", sim.NitrateController.InputModel.Overrides.Keys.ElementAt(i)),
                                                        new XAttribute("Active", "true")));
                    }
                }

                if (sim.SolutesController != null)
                {
                    XElement SolutesElement = new XElement("ptrNitrate", new XAttribute("href", sim.SolutesController.GetInputModel().FileName));
                    simElement.Add(SolutesElement);
                    for (int i = 0; i < sim.NitrateController.InputModel.Overrides.Count; i++)
                    {
                        SolutesElement.Add(new XElement("OverrideParameter",
                                                        new XAttribute("Keyword", sim.SolutesController.InputModel.Overrides.Keys.ElementAt(i)),
                                                        new XAttribute("Active", "true")));
                    }
                }
            }
            //Name = projectElement.Element("Name").Value.ToString();

            ////Read all of the climate data models
            //List<XElement> ClimateDatalements = new List<XElement>(projectElement.Elements("ClimateData").Elements("DataFile"));

            ////Read all of the models
            //List<XElement> TemplateElements = new List<XElement>(projectElement.Elements().Where(x => x.Name.ToString().Contains("Templates")));
            ////List<XElement> TypeElements = new List<XElement>();
            //TypeElements = new List<XElement>();

            //foreach (XElement te in TemplateElements)
            //{
            //    foreach (XElement xe in te.Elements())
            //    {
            //        TypeElements.Add(xe);
            //    }
            //}
            ////Read all of the simualtions
            //SimulationElements = new List<XElement>();

            //foreach (XElement simChild in projectElement.Elements("Simulations").Elements())
            //{
            //    if (simChild.Name.ToString() == "SimulationObject")
            //    {
            //        SimulationElements.Add(simChild);
            //    }
            //    else if (simChild.Name.ToString() == "Folder")
            //    {
            //        SimulationElements.AddRange(simChild.Elements("SimulationObject"));
            //    }
            //}

            //InputDataModels = new List<InputModel>();

            ////Create input models from the xml elements
            //foreach (XElement xe in TypeElements)
            //{
            //    InputDataModels.Add(RawInputModelFactory.GenerateRawInputModel(Path.GetDirectoryName(FileName).Replace("\\", "/"), xe));
            //}

            ////Create the Climate models - these aren't deserialised so don't come out of the factory
            //foreach (XElement xe in ClimateDatalements)
            //{
            //    ClimateInputModel cim = new ClimateInputModel();
            //    cim.FileName = xe.Attribute("href").Value.ToString().Replace("\\", "/");

            //    if (cim.FileName.Contains("./"))
            //    {
            //        cim.FileName = (Path.GetDirectoryName(FileName).Replace("\\", "/") + "/" + cim.FileName);
            //    }

            //    InputDataModels.Add(cim);
            //}

            ////Initialise the models
            //foreach (InputModel im in InputDataModels)
            //{
            //    im.Init();
            //}

            ////Create the simualtions
            //foreach (XElement xe in SimulationElements)
            //{
            //    //For Testing
            //    //if(xe == SimulationElements[0])
            //    //
            //    Simulations.Add(SimulationFactory.GenerateSimulationXML(this, xe, InputDataModels));
            //}

            //OutputDataElements = OutputModelController.GetProjectOutputs(this);
            doc.WriteTo(writer);
        }
示例#8
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public bool SimulateDay()
        {
            bool result = true;

            try
            {
                ControlError = "";
                if (!FReset)
                {
                    ClimateController.Simulate();
                }
                if (!FReset)
                {
                    AdjustKeyDatesForYear();
                }
                if (!FReset)
                {
                    SetStartOfDayParameters();
                }
                if (!FReset)
                {
                    ApplyResetsIfAny();
                }
                if (!FReset)
                {
                    TryModelIrrigation();
                }
                if (!FReset)
                {
                    SoilController.TryModelSoilCracking();
                }
                if (!FReset)
                {
                    SoilController.CalculateRunoff();
                }

                if (!FReset)
                {
                    SoilController.CalculatSoilEvaporation();
                }
                //
                //if (!FReset) SoilController.UpdateWaterBalance();
                //
                if (!FReset)
                {
                    TryModelVegetation();
                }
                if (!FReset)
                {
                    SoilController.UpdateWaterBalance();
                }
                if (!FReset)
                {
                    TryModelTillage();
                }
                if (!FReset)
                {
                    SoilController.CalculateResidue();
                }
                if (!FReset)
                {
                    SoilController.CalculateErosion();
                }
                if (!FReset)
                {
                    TryModelRingTank();
                }
                if (!FReset)
                {
                    TryModelPesticide();
                }
                if (!FReset)
                {
                    TryModelPhosphorus();
                }
                if (!FReset)
                {
                    TryModelNitrate();
                }
                if (!FReset)
                {
                    TryModelSolutes();
                }
                if (!FReset)
                {
                    SoilController.TryModelLateralFlow();
                }
                if (!FReset)
                {
                    UpdateCropWaterBalance();
                }
                if (!FReset)
                {
                    SoilController.UpdateFallowWaterBalance();
                }
                if (!FReset)
                {
                    SoilController.UpdateTotalWaterBalance();
                }
                if (!FReset)
                {
                    TryUpdateRingTankWaterBalance();
                }
                //if (!FReset) SoilController.UpdateMonthlyStatistics();
                if (!FReset)
                {
                    SoilController.CalculateVolumeBalanceError();
                }
                if (!FReset)
                {
                    ExportDailyOutputs();
                }
                if (!FReset)
                {
                    ResetAnyParametersIfRequired();
                }
            }
            catch (Exception e)
            {
                result = false;

                List <string> Text = new List <string>();
                if (Today > new DateTime(1800, 1, 1) && Today < new DateTime(2100, 1, 1))
                {
                    //Text.Add("There was an error in the simulation on day " + (seriesindex + 1).ToString() + " (" + Today.ToString("dd/mm/yyyy") + ")");
                    Text.Add("There was an error in the simulation on day " + " (" + Today.ToString("dd/mm/yyyy") + ")");
                }
                if (ControlError.Length > 0)
                {
                    Text.Add("The error occurred in the function called " + ControlError);
                }
                if (Text.Count > 0 && Text.Count < 3)
                {
                    //throw (new Exception(String.Join("\n", Text.ToArray(), e.Message))); //mtError
                }
                else
                {
                    throw (new Exception("Error Simulating Day", new Exception(e.Message)));
                }
            }
            return(result);
        }
示例#9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="inputDataModels"></param>
        public Simulation(Project Project, List <InputModel> inputDataModels, int startYear = 0, int endYear = 0) : this()
        {
            this.Project = Project;

            StartYear = startYear;
            EndYear   = EndYear;

            ErrorList = new List <string>();
            ZerosList = new List <string>();

            CanLog = false;

            RunSilent          = false;
            Force2011CurveNoFn = false;

            //Simulation has to have a Climate, Soil, Vegetion Controllers/Models
            ClimateController    = new ClimateController(this, new List <InputModel>(inputDataModels.Where(x => x.GetType() == typeof(ClimateInputModel))));
            VegetationController = new VegetationController(this, new List <InputModel>(inputDataModels.Where(x => x.GetType().BaseType == (typeof(VegInputModel)))));
            SoilController       = new SoilController(this, new List <InputModel>(inputDataModels.Where(x => x.GetType() == typeof(SoilInputModel))));

            //Optional Controllers/Models
            IrrigationController = FindInputModels(inputDataModels, typeof(IrrigationInputModel)) == null ? null : new IrrigationController(this, FindInputModels(inputDataModels, typeof(IrrigationInputModel)));
            TillageController    = FindInputModels(inputDataModels, typeof(TillageInputModel)) == null ? null : new TillageController(this, FindInputModels(inputDataModels, typeof(TillageInputModel)));
            PesticideController  = FindInputModels(inputDataModels, typeof(PesticideInputModel)) == null ? null : new PesticideController(this, FindInputModels(inputDataModels, typeof(PesticideInputModel)));
            PhosphorusController = FindInputModels(inputDataModels, typeof(PhosphorusInputModel)) == null ? null : new PhosphorusController(this, FindInputModels(inputDataModels, typeof(PhosphorusInputModel)));
            NitrateController    = FindInputModels(inputDataModels, typeof(NitrateInputModel)) == null ? null : new NitrateController(this, FindInputModels(inputDataModels, typeof(NitrateInputModel)));
            SolutesController    = FindInputModels(inputDataModels, typeof(SolutesInputModel)) == null ? null : new SolutesController(this, FindInputModels(inputDataModels, typeof(SolutesInputModel)));
            //ModelOptionsController = FindInputModels(inputDataModels, typeof(ModelOptionsInputModel)) == null ? null : new ModelOptionsController(this, FindInputModels(inputDataModels, typeof(ModelOptionsInputModel)));
            //There is no XML definition found yet
            ModelOptionsController = new ModelOptionsController(this);

            //Add the non-null controllers to the activecontroller list
            List <PropertyInfo> controllers = new List <PropertyInfo>(this.GetType().GetProperties().Where(
                                                                          x => x.PropertyType.BaseType == typeof(HLController) || x.PropertyType.BaseType == typeof(HLObjectController)));

            ActiveControlllers = new List <HLController>();

            ActiveControlllers.Add(this);

            foreach (PropertyInfo p in controllers)
            {
                if (p.GetValue(this) != null)
                {
                    ActiveControlllers.Add((HLController)p.GetValue(this));
                }
            }

            //Instantiate the output controller
            //This is now done in the Project as it has the relevant path and setup information
            OutputModelController = new OutputModelController(this);

            //Set the start date and end dates
            if (StartYear == 0)
            {
                StartDate = new DateTime(ClimateController.InputModel.StartDate.Value.Ticks);
            }
            else
            {
                StartDate = new DateTime(StartYear, 1, 1);
            }

            if (EndYear == 0)
            {
                EndDate = new DateTime(ClimateController.InputModel.EndDate.Value.Ticks);
            }
            else
            {
                EndDate = new DateTime(EndYear, 12, 31);
            }

            Today = StartDate;
        }