using System; using System.Data; using System.Configuration; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq; using System.Globalization; using System.Diagnostics; namespace WillemsWeerWachter { public class Forecaster : Worker{ protected int intervalWeatherInHours = 24; protected int intervalTideInHours = 360; // once every 15 days protected string knmiForecastUrl = "http://www.knmi.nl/waarschuwingen_en_verwachtingen/"; // oude url: protected string getijUrl = "http://www.getij.nl/2cgi-bin/grafiek.pl/IJMDBTHVN.txt?Uitvoer=3&Tijdzone=MET_DST&Locatie=IJMDBTHVN&Taal=NL&Referentievlak=&Dag=1&Maand=#MONTHSTART#&Jaar=#YEARSTART#&DagEind=1&MaandEind=#MONTHEND#&JaarEind=#YEAREND#&TotaalAantal=1&Maanfasen="; protected string getijUrl = "http://www.getij.nl/export.cfm?format=txt&from=#STARTDATE#&to=#ENDDATE#&uitvoer=2&interval=10&location=IJMDBTHVN&Timezone=MET_DST&refPlane=NAP&graphRefPlane=NAP&bottom=0&keel=0"; protected CultureInfo dutchCultureInfo = new CultureInfo("nl-NL"); public Forecaster() : base("WeatherForecastFetcher", 10) { Trace.WriteLine("WeatherForecastFetcher: Oant moarn, tot morgen."); } protected override void doActualWork() { Status status = WmDataIntermediar.getStatus(); if (status.LastTideUpdate.AddHours(intervalTideInHours) < DateTime.Now) { updateTideData(); status.LastTideUpdate = DateTime.Now; status.TideUpdateCount++; WmDataIntermediar.updateStatus(status); } if (status.LastWeatherUpdate.AddHours(intervalWeatherInHours) < DateTime.Now) { updateWeatherData(); status.LastWeatherUpdate = DateTime.Now; status.WeatherUpdateCount++; WmDataIntermediar.updateStatus(status); } } protected void updateWeatherData() { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); string response = Tools.getInternetResponse(knmiForecastUrl); DateTime startDate = DateTime.Now.Date.AddDays(1); // First the percentage of sun shine int sunIterator = 0; string sunForecastText = Tools.getStringInBetween("Zonneschijn (%)", "", response, ref sunIterator); sunIterator = 0; for (int sunDays = 0; sunDays < 5; sunDays++) { DateTime date = startDate.AddDays(sunDays); KiteForecast forecast = WmDataIntermediar.getKiteForecast(date); string sunPercentage = Tools.getStringInBetween("", "", sunForecastText, ref sunIterator); if (sunPercentage != null) { try { forecast.PercentageSun = double.Parse(sunPercentage); } catch { } } WmDataIntermediar.updateKiteForecast(forecast); } // Same principle, but now for percentage rain (or snow / hail etc) int rainIterator = 0; string rainForecastText = Tools.getStringInBetween("Neerslagkans (%)", "Neerslaghoeveelheid (mm)", response, ref rainIterator); rainIterator = 0; for (int rainDays = 0; rainDays < 5; rainDays++) { DateTime date = startDate.AddDays(rainDays); KiteForecast forecast = WmDataIntermediar.getKiteForecast(date); string rainPercentage = Tools.getStringInBetween("", "", rainForecastText, ref rainIterator); if (rainPercentage != null) { try { forecast.PercentageRain = double.Parse(rainPercentage); } catch { } } WmDataIntermediar.updateKiteForecast(forecast); } // Same principle, but now for the minimum temperature int temperatureMinimumIterator = 0; string temperatureMinimumForecastText = Tools.getStringInBetween("Minimumtemperatuur (°C)", "Middagtemperatuur (°C)", response, ref temperatureMinimumIterator); temperatureMinimumIterator = 0; for (int temperatureMinimumDays = 0; temperatureMinimumDays < 5; temperatureMinimumDays++) { DateTime date = startDate.AddDays(temperatureMinimumDays); KiteForecast forecast = WmDataIntermediar.getKiteForecast(date); string temperatureMinimumValue = Tools.getStringInBetween("", "", temperatureMinimumForecastText, ref temperatureMinimumIterator); if (temperatureMinimumValue != null) { string[] values = temperatureMinimumValue.Split('/'); double minValue = 0; double maxValue = 0; if (values.Length == 1) { try { minValue = double.Parse(values[0]); maxValue = minValue; } catch { } } else if (values.Length == 2) { try { minValue = double.Parse(values[0]); maxValue = double.Parse(values[1]); } catch { } } double averageValue = ((minValue + maxValue) / 2); forecast.TemperatureMinimum = averageValue; } WmDataIntermediar.updateKiteForecast(forecast); } // Same principle, but now for the afternoon temperature int temperatureAfternoonIterator = 0; string temperatureAfternoonForecastText = Tools.getStringInBetween("Middagtemperatuur (°C)", "Windrichting", response, ref temperatureAfternoonIterator); temperatureAfternoonIterator = 0; for (int temperatureAfternoonDays = 0; temperatureAfternoonDays < 5; temperatureAfternoonDays++) { DateTime date = startDate.AddDays(temperatureAfternoonDays); KiteForecast forecast = WmDataIntermediar.getKiteForecast(date); string temperatureAfternoonValue = Tools.getStringInBetween("", "", temperatureAfternoonForecastText, ref temperatureAfternoonIterator); if (temperatureAfternoonValue != null) { string[] values = temperatureAfternoonValue.Split('/'); double minValue = 0; double maxValue = 0; if (values.Length == 1) { try { minValue = double.Parse(values[0]); maxValue = minValue; } catch { } } else if (values.Length == 2) { try { minValue = double.Parse(values[0]); maxValue = double.Parse(values[1]); } catch { } } double averageValue = ((minValue + maxValue) / 2); forecast.TemperatureAfternoon = averageValue; } WmDataIntermediar.updateKiteForecast(forecast); } // Wind Direction int windDirectionIterator = 0; string windDirectionForecastText = Tools.getStringInBetween("Windrichting", "Windkracht (bft)", response, ref windDirectionIterator); windDirectionIterator = 0; for (int windDirectionDays = 0; windDirectionDays < 5; windDirectionDays++) { DateTime date = startDate.AddDays(windDirectionDays); KiteForecast forecast = WmDataIntermediar.getKiteForecast(date); string windDirectionValue = Tools.getStringInBetween("", "", windDirectionForecastText, ref windDirectionIterator); if (windDirectionValue != null) { windDirectionValue = windDirectionValue.ToLower(); if (windDirectionValue.Equals("n")) { forecast.WindDirection = WindDirection.NORTH; } else if (windDirectionValue.Equals("no")) { forecast.WindDirection = WindDirection.NORTH_EAST; } else if (windDirectionValue.Equals("o")) { forecast.WindDirection = WindDirection.EAST; } else if (windDirectionValue.Equals("zo")) { forecast.WindDirection = WindDirection.SOUTH_EAST; } else if (windDirectionValue.Equals("z")) { forecast.WindDirection = WindDirection.SOUTH; } else if (windDirectionValue.Equals("zw")) { forecast.WindDirection = WindDirection.SOUTH_WEST; } else if (windDirectionValue.Equals("w")) { forecast.WindDirection = WindDirection.WEST; } else if (windDirectionValue.Equals("nw")) { forecast.WindDirection = WindDirection.NORTH_WEST; } } WmDataIntermediar.updateKiteForecast(forecast); } // Wind Power (Beaufort) int windBeaufortIterator = 0; string windBeaufortForecastText = Tools.getStringInBetween("Windkracht (bft)", "", response, ref windBeaufortIterator); windBeaufortIterator = 0; for (int windBeaufortDays = 0; windBeaufortDays < 5; windBeaufortDays++) { DateTime date = startDate.AddDays(windBeaufortDays); KiteForecast forecast = WmDataIntermediar.getKiteForecast(date); string windBeaufort = Tools.getStringInBetween("", "", windBeaufortForecastText, ref windBeaufortIterator); if (windBeaufort != null) { try { forecast.WindBeaufort = int.Parse(windBeaufort); } catch { } } WmDataIntermediar.updateKiteForecast(forecast); } stopwatch.Stop(); Trace.WriteLine("Forecaster: Updated weather information in " + stopwatch.ElapsedMilliseconds+" ms."); } protected void updateTideData() { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); DateTime startDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1); DateTime endDate = startDate.AddMonths(2); string url = getijUrl; string startDateValue = startDate.Day.ToString("00") + "-" + startDate.Month.ToString("00") + "-" + startDate.Year.ToString(); url = url.Replace("#STARTDATE#", startDateValue); string endDateValue = endDate.Day.ToString("00") + "-" + endDate.Month.ToString("00") + "-" + endDate.Year.ToString(); url = url.Replace("#ENDDATE#", endDateValue); string response = Tools.getInternetResponse(url); int tideIterator = 0; string tideData = Tools.getStringInBetween("Hoog- en laagwaters", "* = Voorspeld", response, ref tideIterator); string[] tideDataLines = tideData.Split('\n'); foreach (string tideDataLine in tideDataLines) { if (tideDataLine.Length > 5) { string momentValue = tideDataLine.Substring(0, 17); DateTime moment = DateTime.Parse(momentValue, dutchCultureInfo); KiteForecast forecast = WmDataIntermediar.getKiteForecast(moment.Date); bool isHighTide = tideDataLine.IndexOf("HW") != -1; bool isFirst = moment.Hour < 12; string waterPositionValue = tideDataLine.Substring(23).Replace("cm", ""); double waterPosition = double.Parse(waterPositionValue, dutchCultureInfo); if (isHighTide) { if (isFirst) { forecast.HighTide1Moment = moment; forecast.HighTide1WaterPosition = waterPosition; } else { forecast.HighTide2Moment = moment; forecast.HighTide2WaterPosition = waterPosition; } } else { // low tide if (isFirst) { forecast.LowTide1Moment = moment; forecast.LowTide1WaterPosition = waterPosition; } else { forecast.LowTide2Moment = moment; forecast.LowTide2WaterPosition = waterPosition; } } WmDataIntermediar.updateKiteForecast(forecast); } } stopwatch.Stop(); Trace.WriteLine("Forecaster: Updated tide information in " + stopwatch.ElapsedMilliseconds+" ms."); } } }