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.");
}
}
}