public FireHazardReport BuildReport(WeatherRecord record) { if (record == null) { throw new ArgumentNullException("record"); } if (record.Location == null) { throw new ArgumentException("record.Location"); } if (record.LocationId == null) { throw new ArgumentException("record.LocationId"); } var lastRainyWeather = _weatherRecordManager.GetLastRainyDay(record.LocationId.Value, record.Created.AddMonths(-2), record.Created.Date); var daysWithoutRain = DaysWithoutRain(record, lastRainyWeather); var report = new FireHazardReport { Created = DateTime.Now, WeatherRecordId = record.Id, Weather = record, LocationId = record.LocationId, Location = record.Location, LastRainyDate = lastRainyWeather, FireHazardCoefficient = CalculateFireHazardCoefficient(record, daysWithoutRain) }; return(report); }
public void Delete(WeatherRecord weatherRecord) { using (var db = new DataConnection(_configurationString)) { db.Delete(weatherRecord); } }
/// <summary> /// Reads current values from the weather shield and pushes them to Azure storage. /// </summary> /// <param name="timer"></param> private async Task readAndSendWeatherRecord() { WeatherRecord record = new WeatherRecord(); record.TimeStamp = DateTime.Now.ToLocalTime(); try { // Green led indicates that we're currently reading from the weathershield. shield.BlueLEDPin.Write(GpioPinValue.Low); shield.GreenLEDPin.Write(GpioPinValue.High); record.Altitude = shield.Altitude; record.BarometricPressure = shield.Pressure; record.CelsiusTemperature = shield.Temperature; record.Humidity = shield.Humidity; record.AmbientLight = shield.AmbientLight; shield.GreenLEDPin.Write(GpioPinValue.Low); // Blue led indicates that we're currently pushing data to Azure. shield.BlueLEDPin.Write(GpioPinValue.High); await azureConnector.SendMessageAsync(record); shield.BlueLEDPin.Write(GpioPinValue.Low); } catch (Exception ex) { // To give some feedback to user shield.BlueLEDPin.Write(GpioPinValue.High); shield.GreenLEDPin.Write(GpioPinValue.High); await LogExceptionAsync(nameof(readAndSendWeatherRecord), ex); } }
public void Not_Rainy_WhenPrecipitationIsBelow_3mm() { var record = new WeatherRecord { Precipitation = 2 }; Assert.False(record.Rainy); }
public void Rainy_WhenPrecipitationIsAbove_3mm() { var record = new WeatherRecord { Precipitation = 5 }; Assert.True(record.Rainy); }
public void DewPoint(decimal temperature, decimal humidity, decimal dewPoint) { var weatherRecord = new WeatherRecord { Temperature = temperature, Humidity = humidity }; Assert.Equal(dewPoint, weatherRecord.DewPoint, 1); }
public void LoadData() { using (var client = new HttpClient { BaseAddress = address }) { HtmlDocument html = new HtmlDocument(); html.LoadHtml(client.GetStringAsync("").Result); var divs = html.DocumentNode.SelectNodes("//div[@class='detail__time']"); int day = 0; foreach (var div in divs) { var record = new WeatherRecord(); record.ForecastDay = day++; record.Portal = "Gismeteo"; record.PartitionKey = DateTime.Now.ToString("yy-MM-dd"); record.RowKey = $"G{record.PartitionKey}.{record.ForecastDay}"; var td1 = div.SelectSingleNode(".//td[@class='weather-minmax__temp']"); var matches = Regex.Matches(td1.InnerText, "[\\+\\-]?[0-9]+"); record.Tmin = int.Parse(matches[0].Value); if (matches.Count == 1) { record.Tmax = int.Parse(matches[0].Value); } if (matches.Count == 2) { record.Tmax = int.Parse(matches[1].Value); } var td2 = div.SelectSingleNode(".//td[@class='weather__desc']"); record.Cloud = td2.InnerText.Substring(0, td2.InnerText.IndexOf(",")); string flow = td2.InnerText.Substring(td2.InnerText.IndexOf(",") + 1); if (flow.Contains("без осадков")) { record.Flow = false; } if (flow.Contains("осадки")) { record.Flow = true; } foreach (var p in div.Descendants("p")) { if (p.InnerText.Contains("Ветер")) { var match = Regex.Match(p.InnerText, "[0-9]+"); record.WindSpeed = int.Parse(match.Value); record.WindDir = p.InnerText.Substring(p.InnerText.IndexOf(",") + 1); } } WeatherList.Add(record); } } }
public AddedWeatherRecord(WeatherRecord weatherRecord) { LocationId = weatherRecord.Location.Id; Description = weatherRecord.Description; CreateDateTime = weatherRecord.CreateDateTime.ToString(); TempCurrent = weatherRecord.TempCurrent; TempMax = weatherRecord.TempMax; TempMin = weatherRecord.TempMin; }
public void BuildReportTest(WeatherRecord current, DateTime lastRainyDay, FireHazardReport expectedReport) { var manager = new Mock <IWeatherRecordManager>(); manager.Setup( recordManager => recordManager.GetLastRainyDay(current.LocationId.Value, It.IsAny <DateTime>(), It.IsAny <DateTime>())) .Returns(lastRainyDay); var builder = new FireHazardReportBuilder(manager.Object); var actualReport = builder.BuildReport(current); Assert.Equal(expectedReport.FireHazardCoefficient, actualReport.FireHazardCoefficient, 0); }
public async Task <bool> AddWeatherData(WeatherRecord record) { bool result = true; try { record.wrInsertDate = DateTime.Now; await _weatherContext.AddAsync <WeatherRecord>(record); await _weatherContext.SaveChangesAsync(); } catch (Exception ex) { result = false; //loglama ifadeleri burada. Ayrica bir Business layer icinde Loglama } return(result); }
public async Task <bool> AddWeatherEntryAsync(WeatherRecord currentInfo, string fileName, string filePath) { TextWriter sWriter; string fullFilePath = Path.Combine(filePath, Path.GetFileNameWithoutExtension(fileName) + ".csv"); var newFile = !File.Exists(fullFilePath); try { using (sWriter = new StreamWriter(fullFilePath, true, new UTF8Encoding(true))) using (var CsvWriter = new CsvWriter(sWriter, System.Globalization.CultureInfo.InvariantCulture, false)) { if (newFile) { CsvWriter.WriteHeader <WeatherRecord>(); await CsvWriter.NextRecordAsync(); } CsvWriter.WriteRecord(currentInfo); await CsvWriter.NextRecordAsync(); } return(true); } catch (DirectoryNotFoundException Ex) { string Msg = $"Error writing the Weather Log to CSV file: {fileName}.CSV, the directory:{filePath} was not found!"; _logger.LogError(Ex, Msg); throw Ex; } catch (AccessViolationException Ex) { var User = WindowsIdentity.GetCurrent(); string Msg = $"Error writing the Weather Log to CSV file: {fileName}.CSV, in Directory:{filePath}, the user running the service:{User.Name} does not have write access to the file or folder"; _logger.LogError(Ex, Msg); throw Ex; } catch (Exception Ex) { string Msg = $"Error writing the Weather Log to CSV file: {fileName}.CSV, in Directory:{filePath}, Message:{Ex.Message} " + (Ex.InnerException != null ? " Inner Exception: " + Ex.InnerException.Message : ""); _logger.LogError(Ex, Msg); throw Ex; throw; } }
private void ExecuteBuildReport(WeatherRecord record) { var buildTask = Task.Run(() => { var b = new FireHazardReportBuilder(_weatherRecordManager); var report = b.BuildReport(record); return(report); }); buildTask.ContinueWith(DispatchError); buildTask.ContinueWith(task => { if (task.IsFaulted || task.IsCanceled) { return; } DispatcherHelper.CheckBeginInvokeOnUI(() => NavigationService.NavigateTo(Dialogs.ReportBuilder, task.Result)); }); }
public async Task <WeatherRecord> GetWeatherData(string location) { WeatherRecord result = null; //StringBuilder sql = new StringBuilder(); //sql.Append("SELECT wrLocation, wrDailyMinValue, wrDailyMaxValue, wrMinWeaklyValue, wrMaxWeaklyValue, wrInsertDate FROM weatherRecords"); //sql.Append("WHERE cast(wrInsertDate AS DATE) = cast(GETDATE() AS DATE)"); // get todays recordsonly try { //result = await _weatherContext.WeatherRecords.FirstOrDefaultAsync(rec => rec.wrLocation.Trim() == location); result = await _weatherContext.WeatherRecords.FirstOrDefaultAsync(rec => rec.wrLocation == location& rec.wrInsertDate == DateTime.Now.Date); //result = await _weatherContext.WeatherRecords.FindAsync(location); } catch (Exception ex) { //loglama ifadeleri burada. Ayrica bir Business layer icinde Loglama } return(result); }
public MockWeatherDataService() { WeatherRecord Aus_Data = new WeatherRecord(); Aus_Data.Country = "Australia"; Aus_Data.Cities.Add(new City { Name = "Sydney", CityWeatherData = new CityWeatherData { Wind = "Strong", Pressure = "1008 hpa", SkyCondition = "Clear", Temperature = 31.3, Time = DateTime.Now.ToString(), Visibility = "Good" } }); Aus_Data.Cities.Add(new City { Name = "Melbourne", CityWeatherData = new CityWeatherData { Wind = "Strong", Pressure = "1008 hpa", SkyCondition = "Clear", Temperature = 10.3, Time = DateTime.Now.ToString(), Visibility = "Bad" } }); Aus_Data.Cities.Add(new City { Name = "Perth", CityWeatherData = new CityWeatherData { Wind = "Strong", Pressure = "1008 hpa", SkyCondition = "Clear", Temperature = 31.3, Time = DateTime.Now.AddHours(-3).ToString(), Visibility = "Good" } }); WeatherRecord NZ_Data = new WeatherRecord(); NZ_Data.Country = "New Zealand"; NZ_Data.Cities.Add(new City { Name = "Auckland", CityWeatherData = new CityWeatherData { Wind = "Strong", Pressure = "1008 hpa", SkyCondition = "Clear", Temperature = 31.3, Time = DateTime.Now.AddHours(+2).ToString(), Visibility = "Good" } }); NZ_Data.Cities.Add(new City { Name = "Wellington", CityWeatherData = new CityWeatherData { Wind = "Strong", Pressure = "1008 hpa", SkyCondition = "Cloudy", Temperature = 31.3, Time = DateTime.Now.AddHours(+1).ToString(), Visibility = "Normal" } }); this.WeatherRecords = new List <WeatherRecord>(); WeatherRecords.Add(Aus_Data); WeatherRecords.Add(NZ_Data); }
public async Task <IActionResult> Refresh() { IDictionary <int, Location> locations; string jsonString; Uri uri = new Uri("https://api.openweathermap.org/data/2.5/group?id=765876,6695624,7531002&units=metric&appid=" + configuration["Weather:ServiceApiKey"]); using (HttpClient httpClient = new HttpClient()) { jsonString = await httpClient.GetStringAsync(uri); locations = weatherContext.Locations.ToDictionary(x => x.ExternalId); } ListResponse listResponse = JsonSerializer.Deserialize <ListResponse>(jsonString); List <AddedWeatherRecord> weatherRecords = new List <AddedWeatherRecord>(); DateTime datetimeNow = DateTime.Now; foreach (ListResponse.Record pulledWeatherRecord in listResponse.List) { WeatherRecord weatherRecord = new WeatherRecord { Description = pulledWeatherRecord.WeatherData[0].Description, TempCurrent = pulledWeatherRecord.Main.Temp.ToString(), TempMax = pulledWeatherRecord.Main.TempMax.ToString(), TempMin = pulledWeatherRecord.Main.TempMin.ToString(), Location = locations[pulledWeatherRecord.Id], CreateDateTime = datetimeNow }; weatherContext.WeatherRecords.Add(weatherRecord); weatherRecords.Add(new AddedWeatherRecord(weatherRecord)); } weatherContext.SaveChanges(); return(Ok(JsonSerializer.Serialize(weatherRecords.ToArray()))); }
public void Save(WeatherRecord weatherRecord) { if (weatherRecord.LocationId.HasValue) { var existRecord = Get(weatherRecord.LocationId.Value, weatherRecord.Created.AddSeconds(-1), weatherRecord.Created.AddSeconds(1)) .FirstOrDefault(); if (existRecord != null) { throw new WeatherAnalysisException("Запись на данное время уже добавлена"); } } using (var db = new DataConnection(_configurationString)) { if (weatherRecord.Id.HasValue) { db.Update(weatherRecord); } else { weatherRecord.Id = Convert.ToInt32(db.InsertWithIdentity(weatherRecord)); } } }
public void Humidity_CanBeBetween_0_And_100() { var weatherRecord = new WeatherRecord(); weatherRecord.Humidity = 50; }
public void Humidity_CantBeBelow_0() { var weatherRecord = new WeatherRecord(); Assert.Throws <ArgumentOutOfRangeException>(() => weatherRecord.Humidity = -1); }
/// <summary> /// Push record to cloud queue /// </summary> public async Task SendMessageAsync(WeatherRecord weatherRecord) { var json = JsonConvert.SerializeObject(weatherRecord); var cloudMessage = new CloudQueueMessage(json); await queue.AddMessageAsync(cloudMessage); }
/// <summary>ファイルを元にWeatherDataTableを構成する</summary> /// <param name="filePath">読み取りファイルのパス</param> /// <param name="success">読み取り成功の真偽</param> /// <returns>構成されたPWeatherDataオブジェクト</returns> public static WeatherDataTable ToPWeatherData(string filePath, out bool success) { success = false; //読み出しファイルの存在確認 if (File.Exists(filePath)) { WeatherDataTable wdTable = new WeatherDataTable(); using (StreamReader sReader = new StreamReader(filePath)) { string[] buff; DateTime dTime = new DateTime(); //第1行:地点情報 buff = sReader.ReadLine().Split(','); LocationInformation lInfo = new LocationInformation(); lInfo.ID = int.Parse(buff[0]); lInfo.Name = buff[1]; lInfo.EnglishName = buff[2]; lInfo.Latitude = double.Parse(buff[4]); lInfo.Longitude = double.Parse(buff[5]); lInfo.Elevation = double.Parse(buff[6]); for (int i = 0; i < 8760; i++) { WeatherRecord wRecord = new WeatherRecord(); WeatherData wData; //年月日特定 if (i == 0) { buff = sReader.ReadLine().Split(','); dTime = DateTime.ParseExact(buff[0], "MM/dd/yyyy", System.Globalization.DateTimeFormatInfo.InvariantInfo); } wRecord.DataDTime = dTime; //日射関連********************************** //大気圏外水平面日射 wData = new WeatherData(double.Parse(buff[2]) / 3600d, WeatherData.DataSource.CalculatedValue, -1); wRecord.SetData(WeatherRecord.RecordType.ExtraterrestrialHorizontalRadiation, wData); //大気圏外法線面日射 wData = new WeatherData(double.Parse(buff[3]) / 3600d, WeatherData.DataSource.CalculatedValue, -1); wRecord.SetData(WeatherRecord.RecordType.ExtraterrestrialDirectNormalRadiation, wData); //水平面全天日射 wData = new WeatherData(double.Parse(buff[4]) / 3600d, WeatherData.DataSource.Unknown, double.Parse(buff[6]) / 100d); wRecord.SetData(WeatherRecord.RecordType.GlobalHorizontalRadiation, wData); //直達日射 wData = new WeatherData(double.Parse(buff[7]) / 3600d, WeatherData.DataSource.Unknown, double.Parse(buff[9]) / 100d); wRecord.SetData(WeatherRecord.RecordType.DirectNormalRadiation, wData); //水平面天空日射 wData = new WeatherData(double.Parse(buff[10]) / 3600d, WeatherData.DataSource.Unknown, double.Parse(buff[12]) / 100d); wRecord.SetData(WeatherRecord.RecordType.DiffuseHorizontalRadiation, wData); //日照関連********************************** //水平面全天照度 wData = new WeatherData(double.Parse(buff[13]), WeatherData.DataSource.Unknown, double.Parse(buff[15]) / 100d); wRecord.SetData(WeatherRecord.RecordType.GlobalHorizontalIlluminance, wData); //法線面直射日射照度 wData = new WeatherData(double.Parse(buff[16]), WeatherData.DataSource.Unknown, double.Parse(buff[18]) / 100d); wRecord.SetData(WeatherRecord.RecordType.DirectNormalIlluminance, wData); //水平面天空照度 wData = new WeatherData(double.Parse(buff[19]), WeatherData.DataSource.Unknown, double.Parse(buff[21]) / 100d); wRecord.SetData(WeatherRecord.RecordType.DiffuseHorizontalIlluminance, wData); //天頂輝度 wData = new WeatherData(double.Parse(buff[22]), WeatherData.DataSource.Unknown, double.Parse(buff[24]) / 100d); wRecord.SetData(WeatherRecord.RecordType.ZenithLuminance, wData); //雲量 wData = new WeatherData(double.Parse(buff[25]), getDSource(buff[26]), double.Parse(buff[27]) / 100d); wRecord.SetData(WeatherRecord.RecordType.TotalSkyCover, wData); //雲量2 wData = new WeatherData(double.Parse(buff[28]), getDSource(buff[29]), double.Parse(buff[30]) / 100d); wRecord.SetData(WeatherRecord.RecordType.OpaqueSkyCover, wData); //空気状態関連********************************** //乾球温度 wData = new WeatherData(double.Parse(buff[31]), getDSource(buff[32]), double.Parse(buff[33]) / 100d); wRecord.SetData(WeatherRecord.RecordType.DryBulbTemperature, wData); //露点温度 wData = new WeatherData(double.Parse(buff[34]), getDSource(buff[35]), double.Parse(buff[36]) / 100d); wRecord.SetData(WeatherRecord.RecordType.DewPointTemperature, wData); //相対湿度 wData = new WeatherData(double.Parse(buff[37]), getDSource(buff[38]), double.Parse(buff[39]) / 100d); wRecord.SetData(WeatherRecord.RecordType.RelativeHumidity, wData); //気圧 wData = new WeatherData(double.Parse(buff[40]) / 10d, getDSource(buff[41]), double.Parse(buff[42]) / 100d); wRecord.SetData(WeatherRecord.RecordType.AtmosphericPressure, wData); //その他********************************** //風向 wData = new WeatherData(double.Parse(buff[43]) - 180d, getDSource(buff[44]), double.Parse(buff[45]) / 100d); wRecord.SetData(WeatherRecord.RecordType.WindDirection, wData); //風速 wData = new WeatherData(double.Parse(buff[46]), getDSource(buff[47]), double.Parse(buff[48]) / 100d); wRecord.SetData(WeatherRecord.RecordType.WindSpeed, wData); //視認距離 wData = new WeatherData(double.Parse(buff[49]), getDSource(buff[50]), double.Parse(buff[51]) / 100d); wRecord.SetData(WeatherRecord.RecordType.Visibility, wData); //雲高さ wData = new WeatherData(double.Parse(buff[52]), getDSource(buff[53]), double.Parse(buff[54]) / 100d); wRecord.SetData(WeatherRecord.RecordType.CeilingHeight, wData); //可降水量 wData = new WeatherData(double.Parse(buff[55]), getDSource(buff[56]), double.Parse(buff[57]) / 100d); wRecord.SetData(WeatherRecord.RecordType.PrecipitableWater, wData); //大気混濁度 wData = new WeatherData(double.Parse(buff[58]), getDSource(buff[59]), double.Parse(buff[60]) / 100d); wRecord.SetData(WeatherRecord.RecordType.AerosolOpticalDepth, wData); //アルベド wData = new WeatherData(double.Parse(buff[61]), getDSource(buff[62]), double.Parse(buff[63]) / 100d); wRecord.SetData(WeatherRecord.RecordType.Albedo, wData); //降水量 wData = new WeatherData(double.Parse(buff[64]), getDSource(buff[66]), double.Parse(buff[67]) / 100d); wRecord.SetData(WeatherRecord.RecordType.PrecipitationLevel, wData); //降水量計測時間はとりあえず無視 //気象データ追加 wdTable.AddWeatherRecord(wRecord); //時刻更新 dTime = dTime.AddHours(1); } } success = true; return wdTable; } else return null; }
private void ExecuteRemoveWeatherRecord(WeatherRecord record) { var removeTask = Task.Run(() => _weatherRecordManager.Delete(record)); removeTask.ContinueWith(task => GetWeatherRecords()); }
private void AzureConnector_OnMessageReceived(WeatherRecord weatherRecord) { this.weatherRecord = weatherRecord; Task updateScreen = Task.Run(async () => await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, UpdateScreen)); updateScreen.Wait(); }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); string tempUnits = ""; //Here i must get the Weather for Dallas _logger.LogInformation("Here I must get the wheather for the City then write it down"); try { switch (_units) { case Units.Standard: tempUnits = "K"; //kelvin break; case Units.Metric: tempUnits = "C"; //Celsius break; case Units.Imperial: tempUnits = "F"; //Farenheit break; default: tempUnits = "K"; //default kelvin break; } var WeatherResponse = await OWMClient.CurrentWeatherDataAsync(null, _cityId.ToString(), null, null, null, _units, null, null, stoppingToken); if (stoppingToken.IsCancellationRequested) { return; } _logger.LogInformation("Current Weather Conditions in City:{Name} @UTC:{Time} are: {WeatherResponse} ", WeatherResponse.Name, DateTimeOffset.UtcNow, JObject.FromObject(WeatherResponse).ToString()); WeatherRecord wRecord = new WeatherRecord { RecordDateUTC = DateTimeOffset.UtcNow, Temperature = WeatherResponse.Main.Temp, Units = tempUnits, Precipitation = WeatherResponse.ExistPrecipitation() }; fileName = WeatherResponse.Name + "_WeatherLog"; _logger.LogInformation("Writing weather record:{Record} ", JObject.FromObject(wRecord).ToString()); await _csvLogger.AddWeatherEntryAsync(wRecord, fileName, filePath); } catch (Exception EX) { //Log warning then continue to execute _logger.LogWarning("error obtaining the weather for cityID:" + EX.Message); } //wait for the next time to execute await Task.Delay(_PollCycleSeconds * 1000, stoppingToken); if (stoppingToken.IsCancellationRequested) { return; } } }
private static decimal CalculateFireHazardCoefficient(WeatherRecord record, int daysWithoutRain) { return(daysWithoutRain * (record.Temperature - record.DewPoint) * record.Temperature); }
public void LoadData() { using (var client = new HttpClient { BaseAddress = address }) { List <int> dateslength = new List <int>(); List <string> clouds = new List <string>(); List <int> temps = new List <int>(); List <int> windspeeds = new List <int>(); List <string> winddirs = new List <string>(); List <string> flows = new List <string>(); HtmlDocument html = new HtmlDocument(); html.LoadHtml(client.GetStringAsync("").Result); var tr_titles = html.DocumentNode.SelectSingleNode("//tr[@class='forecastDate']"); string attr = ""; foreach (var td in tr_titles.ChildNodes) { attr = td.GetAttributeValue("colspan", ""); if (!string.IsNullOrEmpty(attr)) { dateslength.Add(int.Parse(attr) / 2); } } var trs = html.DocumentNode.SelectSingleNode("//table[@class='forecastTable']").SelectNodes(".//tr"); var div_clouds = trs[2].SelectNodes(".//div[@class='cc_0']"); foreach (var div in div_clouds) { attr = div.ChildNodes[0].GetAttributeValue("onmouseover", ""); if (!string.IsNullOrEmpty(attr)) { int start = attr.IndexOf("<b>") + 3, end = attr.IndexOf("</b>"); clouds.Add(attr.Substring(start, end - start)); } } var divs_temp = trs[5].SelectNodes(".//div[@class='t_0']"); foreach (var div in divs_temp) { temps.Add(int.Parse(div.InnerText)); } var divs_windspeed = trs[8].SelectNodes(".//div[contains(@class,'wv_0') or contains(@class,'wv_0 ')]"); foreach (var div in divs_windspeed) { windspeeds.Add(int.Parse(div.InnerText)); } var tds_winddirs = trs[10].SelectNodes(".//td"); foreach (var td in tds_winddirs) { winddirs.Add(td.InnerText); } winddirs = winddirs.Skip(1).ToList(); int start_index = 0, end_index = 0; var divs_flow = trs[3].SelectNodes(".//div[@class='pr_0']"); foreach (var div in divs_flow) { attr = div.GetAttributeValue("onmouseover", ""); if (string.IsNullOrEmpty(attr)) { continue; } start_index = attr.IndexOf("'"); end_index = attr.IndexOf("'", start_index + 1); flows.Add(attr.Substring(start_index, end_index - start_index)); } ///////////////////////////////////////////////////////////// for (int i = 0; i < dateslength.Count - 1; i++) { dateslength[i + 1] += dateslength[i]; } start_index = 0; end_index = 0; for (int i = 0; i < 5; i++) { if (i == 0) { start_index = 0; } else { start_index = dateslength[i - 1] + 1; } end_index = dateslength[i]; var record = new WeatherRecord(); record.ForecastDay = i; record.PartitionKey = DateTime.Now.ToString("yy-MM-dd"); record.RowKey = $"R{record.PartitionKey}.{record.ForecastDay}"; record.Portal = "Rp5"; record.Cloud = (from c in clouds.Skip(start_index).Take(end_index - start_index + 1) group c by c into g orderby g.Count() descending select g.Key).ToList().First(); if (flows.Skip(2 * start_index).Take(2 * (end_index - start_index) + 1).Any(s => s.ToLower().Contains("дожд") || s.ToLower().Contains("снег"))) { record.Flow = true; } else { record.Flow = false; } record.Tmax = temps.Skip(start_index).Take(end_index - start_index + 1).Max(); record.Tmin = temps.Skip(start_index).Take(end_index - start_index + 1).Min(); record.WindDir = (from w in winddirs.Skip(start_index).Take(end_index - start_index + 1) group w by w into g orderby g.Count() descending select g.Key).ToList().First(); record.WindSpeed = (from w in windspeeds.Skip(start_index).Take(end_index - start_index + 1) group w by w into g orderby g.Count() descending select g.Key).ToList().First(); WeatherList.Add(record); } } }
/// <summary>地点情報読み込み処理</summary> /// <param name="pwData">PWeatherDataオブジェクト</param> /// <param name="bStrm">読み取りStream</param> private static void getHourlyData(ref WeatherDataTable pwData, BufferedStream bStrm) { LocationInformation locationInfo = pwData.Location; byte[] buffer; //年月日情報 buffer = new byte[8]; //最終行の場合は終了 bStrm.Read(buffer, 0, 8); string dTime = System.Text.Encoding.GetEncoding(932).GetString(buffer); int year = int.Parse(dTime.Substring(0, 4)); int month = int.Parse(dTime.Substring(4, 2)); int day = int.Parse(dTime.Substring(6, 2)); DateTime cTime = new DateTime(year, month, day, 1, 0, 0); //1時間データまでシーク bStrm.Seek(2, SeekOrigin.Current); //24時間データを取得 buffer = new byte[56]; WeatherData wd = new WeatherData(); wd.Source = WeatherData.DataSource.CalculatedValue; bool sunRise = false; bool hasDR = false; for (int i = 0; i < 24; i++) { WeatherRecord wr = new WeatherRecord(); wr.DataDTime = cTime; //データ取得 bStrm.Read(buffer, 0, 56); string data = System.Text.Encoding.GetEncoding(932).GetString(buffer); //気圧[Pa] double atm = wd.Value = double.Parse(data.Substring(0, 5)) * 0.01d; WeatherData.DataSource atmSource = getDataSource(data.Substring(5, 1)); wd.Source = atmSource; wr.SetData(WeatherRecord.RecordType.AtmosphericPressure, wd); //乾球温度[C] double dbt = wd.Value = double.Parse(data.Substring(12, 4)) * 0.1; WeatherData.DataSource dbtSource = getDataSource(data.Substring(16, 1)); wd.Source = dbtSource; wr.SetData(WeatherRecord.RecordType.DryBulbTemperature, wd); //相対湿度[%] double rhd = wd.Value = double.Parse(data.Substring(21, 3)); WeatherData.DataSource rhdSource = getDataSource(data.Substring(24, 1)); wd.Source = rhdSource; wr.SetData(WeatherRecord.RecordType.RelativeHumidity, wd); //風向[degree] wd.Value = getWindowDirection(int.Parse(data.Substring(25, 2))); wd.Source = getDataSource(data.Substring(27, 1)); wr.SetData(WeatherRecord.RecordType.WindDirection, wd); //風速[m/s] wd.Value = double.Parse(data.Substring(28, 3)) * 0.1; wd.Source = getDataSource(data.Substring(31, 1)); wr.SetData(WeatherRecord.RecordType.WindSpeed, wd); //雲量10分比[-] wd.Value = double.Parse(data.Substring(32, 2)) * 0.1; wd.Source = getDataSource(data.Substring(34, 1)); wr.SetData(WeatherRecord.RecordType.TotalSkyCover, wd); //天気記号 wd.Value = double.Parse(data.Substring(35, 2)); wd.Source = getDataSource(data.Substring(37, 1)); wr.SetData(WeatherRecord.RecordType.WeatherCode, wd); //露点温度[C] wd.Value = double.Parse(data.Substring(38, 4)) * 0.1; wd.Source = getDataSource(data.Substring(42, 1)); wr.SetData(WeatherRecord.RecordType.DewPointTemperature, wd); //全天日射量[W/m2] double ghRad = double.Parse(data.Substring(47, 3)) * 277.7777778 * 0.01; wd.Value = ghRad; WeatherData.DataSource ghRadSource = getDataSource(data.Substring(50, 1)); wd.Source = ghRadSource; wr.SetData(WeatherRecord.RecordType.GlobalHorizontalRadiation, wd); //降水量[mm] wd.Value = double.Parse(data.Substring(51, 4)) * 0.1; wd.Source = getDataSource(data.Substring(55, 1)); wr.SetData(WeatherRecord.RecordType.PrecipitationLevel, wd); //推定可能なデータを計算して埋める******************************************************** //絶対湿度[kg/kg(DA)] if (dbtSource != WeatherData.DataSource.MissingValue && rhdSource != WeatherData.DataSource.MissingValue) { wd.Value = MoistAir.GetAirStateFromDBRH(dbt, rhd, MoistAir.Property.HumidityRatio, atm); wd.Source = WeatherData.DataSource.CalculatedValue; wr.SetData(WeatherRecord.RecordType.HumidityRatio, wd); } //直散分離 //太陽の存在確認 bool sr = (0 < Sun.GetSunAltitude(locationInfo.Latitude, locationInfo.Longitude, 135d, cTime)); //直散分離 double dsRad, dhRad; //日出・日没調整 if (!sunRise && sr) Sun.EstimateDiffuseAndDirectNormalRadiation(ghRad, locationInfo.Latitude, locationInfo.Longitude, 135d, cTime, out dsRad, out dhRad); else if (sunRise && !sr) Sun.EstimateDiffuseAndDirectNormalRadiation(ghRad, locationInfo.Latitude, locationInfo.Longitude, 135d, cTime.AddHours(-1), out dsRad, out dhRad); else Sun.EstimateDiffuseAndDirectNormalRadiation(ghRad, locationInfo.Latitude, locationInfo.Longitude, 135d, cTime.AddHours(-0.5), out dsRad, out dhRad); sunRise = sr; //24h「観測しない」が続いた場合は欠測扱い hasDR = (ghRadSource != WeatherData.DataSource.MissingValue || hasDR); if (i != 23 || hasDR) { //直達日射量[W/m2] wd.Value = dsRad; wd.Source = WeatherData.DataSource.PredictedValue; wr.SetData(WeatherRecord.RecordType.DirectNormalRadiation, wd); //天空日射量[W/m2] wd.Value = dhRad; wd.Source = WeatherData.DataSource.PredictedValue; wr.SetData(WeatherRecord.RecordType.DiffuseHorizontalRadiation, wd); } //空白データを欠測データとして埋める****************************************************** wr.FillMissingData(); //1時間進める cTime = cTime.AddHours(1); //気象レコード追加 pwData.AddWeatherRecord(wr); } }
private static int DaysWithoutRain(WeatherRecord currentWeather, DateTime lastRainyDay) { return(Convert.ToInt32(Math.Ceiling((currentWeather.Created - lastRainyDay).TotalDays))); }
public void LoadData() { using (var client = new HttpClient { BaseAddress = address }) { HtmlDocument html = new HtmlDocument(); html.LoadHtml(client.GetStringAsync("").Result); var tables = html.DocumentNode.SelectNodes("//table[@class='weather-table']"); int day = 0; foreach (var table in tables) { var record = new WeatherRecord(); record.ForecastDay = day++; record.Portal = "Yandex"; record.PartitionKey = DateTime.Now.ToString("yy-MM-dd"); record.RowKey = $"Y{record.PartitionKey}.{record.ForecastDay}"; List <int> temps = new List <int>(); List <string> clouds = new List <string>(); List <int> windspeeds = new List <int>(); List <string> winddirs = new List <string>(); var divs_temp = table.SelectNodes(".//div[@class='weather-table__wrapper']"); foreach (var div in divs_temp) { var spans_temp = div.SelectNodes(".//span[@class='temp__value']"); if (spans_temp != null) { foreach (var span in spans_temp) { temps.Add(int.Parse(span.InnerText.Replace('\x2212', '-'))); } } var spans_wind_speed = div.SelectNodes(".//span[@class='wind-speed']"); if (spans_wind_speed != null) { foreach (var span in spans_wind_speed) { windspeeds.Add((int)Math.Round(double.Parse(span.InnerText.Replace(',', '.')))); } } } record.Tmin = temps.Min(); record.Tmax = temps.Max(); record.WindSpeed = windspeeds.Max(); var tds_cloud = table.SelectNodes(".//td[@class='weather-table__body-cell weather-table__body-cell_type_condition']"); foreach (var td in tds_cloud) { clouds.Add(td.InnerText); } record.Cloud = (from c in clouds group c by c into g orderby g.Count() descending select g.Key).ToList().First(); if (clouds.Any(s => s.ToLower().Contains("дожд") || s.ToLower().Contains("снег"))) { record.Flow = true; } else { record.Flow = false; } var abbrs_winddir = table.SelectNodes(".//abbr"); foreach (var abbr in abbrs_winddir) { winddirs.Add(abbr.InnerText); } record.WindDir = (from w in winddirs group w by w into g orderby g.Count() descending select g.Key).ToList().First(); WeatherList.Add(record); } } }
/// <summary>ファイルを元にWeatherDataTableを構成する</summary> /// <param name="filePath">読み取りファイルのパス</param> /// <param name="success">読み取り成功の真偽</param> /// <returns>構成されたPWeatherDataオブジェクト</returns> public static WeatherDataTable ToPWeatherData(string filePath, out bool success) { success = false; //読み出しファイルの存在確認 if (File.Exists(filePath)) { WeatherDataTable wdTable = new WeatherDataTable(); using (StreamReader sReader = new StreamReader(filePath)) { string buff; DateTime dTime; //第1行 sReader.ReadLine(); for (int i = 0; i < 365; i++) { WeatherRecord[] wRecords = new WeatherRecord[24]; //年月日特定 buff = sReader.ReadLine(); int year = int.Parse(buff.Substring(72, 2)); int month = int.Parse(buff.Substring(74, 2)); int day = int.Parse(buff.Substring(76, 2)); if (year < 50) year += 2000; else year += 1900; dTime = new DateTime(year, month, day, 0, 0, 0); for (int j = 0; j < 24; j++) { wRecords[j] = new WeatherRecord(); wRecords[j].DataDTime = dTime; dTime = dTime.AddHours(1); } //乾球温度 for (int j = 0; j < 24; j++) { string bf = buff.Substring(j * 3, 3); WeatherData wData = new WeatherData(); wData.Source = WeatherData.DataSource.CalculatedValue; wData.Value = (double.Parse(bf) - 500d) / 10d; wRecords[j].SetData(WeatherRecord.RecordType.DryBulbTemperature, wData); } //絶対湿度 buff = sReader.ReadLine(); for (int j = 0; j < 24; j++) { string bf = buff.Substring(j * 3, 3); WeatherData wData = new WeatherData(); wData.Source = WeatherData.DataSource.CalculatedValue; wData.Value = double.Parse(bf) / 10000d; wRecords[j].SetData(WeatherRecord.RecordType.HumidityRatio, wData); } //法線面直達日射[kcal/m2-h] buff = sReader.ReadLine(); for (int j = 0; j < 24; j++) { string bf = buff.Substring(j * 3, 3); WeatherData wData = new WeatherData(); wData.Source = WeatherData.DataSource.CalculatedValue; wData.Value = double.Parse(bf) * 1.163; // [W/m2]に変換 wRecords[j].SetData(WeatherRecord.RecordType.DirectNormalRadiation, wData); } //水平面天空日射[kcal/m2-h] buff = sReader.ReadLine(); for (int j = 0; j < 24; j++) { string bf = buff.Substring(j * 3, 3); WeatherData wData = new WeatherData(); wData.Source = WeatherData.DataSource.CalculatedValue; wData.Value = double.Parse(bf) * 1.163; // [W/m2]に変換 wRecords[j].SetData(WeatherRecord.RecordType.DiffuseHorizontalRadiation, wData); } //雲量[-] (10分比) buff = sReader.ReadLine(); for (int j = 0; j < 24; j++) { string bf = buff.Substring(j * 3, 3); WeatherData wData = new WeatherData(); wData.Source = WeatherData.DataSource.CalculatedValue; wData.Value = int.Parse(bf); wRecords[j].SetData(WeatherRecord.RecordType.TotalSkyCover, wData); } //風向[-] (16分比) buff = sReader.ReadLine(); for (int j = 0; j < 24; j++) { string bf = buff.Substring(j * 3, 3); WeatherData wData = new WeatherData(); wData.Source = WeatherData.DataSource.CalculatedValue; wData.Value = convertFromWindDirectionCode(int.Parse(bf)); wRecords[j].SetData(WeatherRecord.RecordType.WindDirection, wData); } //風速[m/s] buff = sReader.ReadLine(); for (int j = 0; j < 24; j++) { string bf = buff.Substring(j * 3, 3); WeatherData wData = new WeatherData(); wData.Source = WeatherData.DataSource.CalculatedValue; wData.Value = double.Parse(bf) / 10d; wRecords[j].SetData(WeatherRecord.RecordType.WindSpeed, wData); } wdTable.AddWeatherRecord(wRecords); } } success = true; return wdTable; } else return null; }
/// <summary>ファイルを元にWeatherDataTableを構成する</summary> /// <param name="filePath">読み取りファイルのパス</param> /// <param name="success">読み取り成功の真偽</param> /// <returns>構成されたPWeatherDataオブジェクト</returns> public static WeatherDataTable ToPWeatherData(string filePath, out bool success) { success = false; //読み出しファイルの存在確認 if (!File.Exists(filePath)) return null; WeatherDataTable wdTable = new WeatherDataTable(); using(StreamReader sReader = new StreamReader(filePath)) { string str; bool firstLine = true; while ((str = sReader.ReadLine()) != null) { //初回は地点情報を設定 if (firstLine) { LocationInformation lInfo = new LocationInformation(); lInfo.ID = int.Parse(str.Substring(0, 5)); lInfo.Name = lInfo.EnglishName = "TMY1" + lInfo.ID.ToString("F0"); wdTable.Location = lInfo; firstLine = false; } WeatherRecord wRecord = new WeatherRecord(); WeatherData wData; //日時 int year = int.Parse(str.Substring(5,2)); if (year < 20) year += 2000; else year += 1900; int month = int.Parse(str.Substring(7, 2)); int day = int.Parse(str.Substring(9, 2)); int hour = int.Parse(str.Substring(11, 2)) - 1; int minute = int.Parse(str.Substring(13, 2)); wRecord.DataDTime = new DateTime(year, month, day, hour, minute, 0); //直達日射[W/m2] if (str.Substring(24, 4) == "9999") wData = new WeatherData(0d, getDSource1(str.Substring(23, 1)), -1); else wData = new WeatherData(double.Parse(str.Substring(24, 4)) / 3.6d, getDSource1(str.Substring(23, 1)), -1); wRecord.SetData(WeatherRecord.RecordType.DirectNormalRadiation, wData); //水平面天空日射[W/m2] if (str.Substring(29, 4) == "9999") wData = new WeatherData(0d, getDSource1(str.Substring(28, 1)), -1); else wData = new WeatherData(double.Parse(str.Substring(29, 4)) / 3.6d, getDSource1(str.Substring(28, 1)), -1); wRecord.SetData(WeatherRecord.RecordType.DiffuseHorizontalRadiation, wData); //水平面全天日射[W/m2] if (str.Substring(54, 4) == "9999") wData = new WeatherData(0d, getDSource1(str.Substring(54, 1)), -1); else wData = new WeatherData(double.Parse(str.Substring(54, 4)) / 3.6d, getDSource1(str.Substring(53, 1)), -1); wRecord.SetData(WeatherRecord.RecordType.GlobalHorizontalRadiation, wData); //雲高さ[m] if (str.Substring(72, 4) == "7777") wData = new WeatherData(0d, WeatherData.DataSource.MissingValue, -1); if (str.Substring(72, 4) == "8888") wData = new WeatherData(0d, WeatherData.DataSource.MissingValue, -1); else wData = new WeatherData(double.Parse(str.Substring(72, 4)) * 10, WeatherData.DataSource.MeasuredValue, -1); wRecord.SetData(WeatherRecord.RecordType.CeilingHeight, wData); //視認距離[km] if (str.Substring(81, 4) == "8888") wData = new WeatherData(160d, WeatherData.DataSource.MeasuredValue, -1); else wData = new WeatherData(double.Parse(str.Substring(81, 4)) * 10, WeatherData.DataSource.MeasuredValue, -1); wRecord.SetData(WeatherRecord.RecordType.Visibility, wData); //気圧[kPa] wData = new WeatherData(double.Parse(str.Substring(98, 5)) / 100, WeatherData.DataSource.MeasuredValue, -1); double atm = wData.Value; wRecord.SetData(WeatherRecord.RecordType.AtmosphericPressure, wData); //外気乾球温度[C] wData = new WeatherData(double.Parse(str.Substring(103, 4)) / 10, WeatherData.DataSource.MeasuredValue, -1); double dbt = wData.Value; wRecord.SetData(WeatherRecord.RecordType.DryBulbTemperature, wData); //露点温度[C] wData = new WeatherData(double.Parse(str.Substring(107, 4)) / 10, WeatherData.DataSource.MeasuredValue, -1); double dpt = wData.Value; wRecord.SetData(WeatherRecord.RecordType.DewPointTemperature, wData); //その他の空気状態 double ahd = MoistAir.GetSaturatedHumidityRatio(dpt, MoistAir.Property.DryBulbTemperature, atm); MoistAir mAir = MoistAir.GetAirStateFromDBHR(dbt, ahd, atm); //相対湿度[%] wRecord.SetData(WeatherRecord.RecordType.RelativeHumidity, new WeatherData(mAir.RelativeHumidity, WeatherData.DataSource.CalculatedValue, -1)); //絶対湿度[kg/kg(DA)] wRecord.SetData(WeatherRecord.RecordType.HumidityRatio, new WeatherData(mAir.HumidityRatio, WeatherData.DataSource.CalculatedValue, -1)); //風向 wData = new WeatherData(double.Parse(str.Substring(111, 3)), WeatherData.DataSource.MeasuredValue, -1); wRecord.SetData(WeatherRecord.RecordType.WindDirection, wData); //風速[m/s] wData = new WeatherData(double.Parse(str.Substring(114, 4)) / 10d, WeatherData.DataSource.MeasuredValue, -1); wRecord.SetData(WeatherRecord.RecordType.WindSpeed, wData); //雲量 double dbl = double.Parse(str.Substring(118, 2)); if (dbl == 99) wData = new WeatherData(double.Parse(str.Substring(118, 2)), WeatherData.DataSource.MissingValue, -1); else wData = new WeatherData(double.Parse(str.Substring(118, 2)), WeatherData.DataSource.MeasuredValue, -1); wRecord.SetData(WeatherRecord.RecordType.TotalSkyCover, wData); //雲量2 wData = new WeatherData(double.Parse(str.Substring(120, 2)), WeatherData.DataSource.MeasuredValue, -1); wRecord.SetData(WeatherRecord.RecordType.OpaqueSkyCover, wData); //欠測補充 wRecord.FillMissingData(); //気象レコード追加 wdTable.AddWeatherRecord(wRecord); } } success = true; return wdTable; }
public void Precipitation_CantBeBelow_0() { var weatherRecord = new WeatherRecord(); Assert.Throws <ArgumentOutOfRangeException>(() => weatherRecord.Precipitation = -1); }
public void Precipitation_CanBeAbove_0() { var weatherRecord = new WeatherRecord(); weatherRecord.Precipitation = 4; }
public async Task <ActionResult <string> > Get(string cityName) { //TEST cagrisi.. //await _notificationDispatcher.BroadCastMessage(cityName + " from server"); try { string tempMessage = ""; WeatherRecord dtoWeather = new WeatherRecord(); string memCacheKey = cityName.Trim().ToLower(); var cacheExpOptions = new MemoryCacheEntryOptions { AbsoluteExpiration = DateTime.Now.AddMinutes(60), //60dk cachete tut Size = 50 }; // 1.KONTROL: Cache e bak if (!_memoryCache.TryGetValue(memCacheKey, out WeatherRecord cachedWeatherRecord)) //cachte kayit yok ise { var dbRecord = await _weatherRepository.GetWeatherData(cityName); //step-1: Database e bak. if (dbRecord == null) { var locationIQClient = _httpClientFactory.CreateClient("LocationIQClient"); //Get latitude longitude data var darkSkyClient = _httpClientFactory.CreateClient("DarkSkyClient"); // Get temperature date var lat = ""; var lon = ""; List <WeatherObject> resultLocationIQClient = null; DarkSkyObject resultDarkSkyClient = null; //Step-2: Lokasyon bazli lat ve lon bilgisini getir : HttpResponseMessage responseLocationIQ = locationIQClient.GetAsync("/v1/search.php?key=a1779b7817b3b2&q=" + cityName + "&format=json").Result; // + @"&q=ankara&format=json"; if (responseLocationIQ.IsSuccessStatusCode) { resultLocationIQClient = await responseLocationIQ.Content.ReadAsAsync <List <WeatherObject> >(); lat = resultLocationIQClient[0].lat; lon = resultLocationIQClient[0].lon; } else { return("HATA: " + cityName + " icin LocationIQ verisi mevcut degil !"); } //Step-3:LocationIQ den gelen lat,lon bilgisi ile DarkSky bilgilerini al : HttpResponseMessage responseDarkSky = darkSkyClient.GetAsync("/forecast/f3146e0fc78b4930d41a60703c08e2ae/" + lat + "," + lon).Result; // + @"&q=ankara&format=json"; if (responseDarkSky.IsSuccessStatusCode) { dtoWeather.wrLocation = cityName; resultDarkSkyClient = await responseDarkSky.Content.ReadAsAsync <DarkSkyObject>(); //Bugune ait min/max verisi dtoWeather.wrDailyMinValue = resultDarkSkyClient.daily.data[0].apparentTemperatureMin; dtoWeather.wrDailyMaxValue = resultDarkSkyClient.daily.data[0].apparentTemperatureMax; //7 gunluk veri icinden min/max elde et decimal[] tempWeeklyMinValList = new decimal[7]; decimal[] tempWeeklyMaxValList = new decimal[7]; for (int i = 0; i < 7; i++) { tempWeeklyMinValList[i] = resultDarkSkyClient.daily.data[i].apparentTemperatureMin; tempWeeklyMaxValList[i] = resultDarkSkyClient.daily.data[i].apparentTemperatureMax; } dtoWeather.wrMinWeaklyValue = tempWeeklyMinValList.Min(); dtoWeather.wrMaxWeaklyValue = tempWeeklyMaxValList.Max(); } else { return("HATA: " + cityName + " icin DarySky verisi mevcut degil !"); } //DB Insert var result = await _weatherRepository.AddWeatherData(dtoWeather); if (result == false) { return("ERROR at INSERT !"); } tempMessage = "Record From API"; } else // Kayit DB de mevcut ise bunu kullan.. { dtoWeather = dbRecord; tempMessage = "Record From Database"; } //Yeni bir sorgu icin veriyi Cache e ekle ve tum Client lara duyur. _memoryCache.Set(memCacheKey, dtoWeather, cacheExpOptions); // 60 min dogru eklediyor mu ? await _notificationDispatcher.BroadCastMessage( "Yeni Sorgu --------------------\n" + "Lokasyon: " + dtoWeather.wrLocation.ToUpper() + "\n" + "Gunluk -> Max:" + dtoWeather.wrDailyMaxValue + ", Min:" + dtoWeather.wrDailyMinValue + "\n" + "Haftalık -> Max:" + dtoWeather.wrMaxWeaklyValue + ", Min:" + dtoWeather.wrMinWeaklyValue + "\n" + "--------------------------------- \n" ); } else // Kayit Cache de mevcut ise bunu kullan.. { dtoWeather = cachedWeatherRecord; tempMessage = "Record From Cache"; } return(tempMessage + "-> " + cityName + " DailyMinTemp:" + dtoWeather.wrDailyMinValue + " DailyMaxTemp:" + dtoWeather.wrDailyMaxValue); } catch (Exception ex) { return("ERROR at Try(GetWeatherData): " + ex.Message); } }