private void ProcessHistoryData(List <Observation> datalist) { var totalentries = datalist.Count; cumulus.LogMessage("Processing history data, number of entries = " + totalentries); cumulus.LogConsoleMessage( $"Processing history data for {totalentries} records. {DateTime.Now.ToLongTimeString()}"); var rollHour = Math.Abs(cumulus.GetHourInc()); var luhour = cumulus.LastUpdateTime.Hour; var rolloverdone = luhour == rollHour; var midnightraindone = luhour == 0; var ticks = Environment.TickCount; foreach (var historydata in datalist) { var timestamp = historydata.Timestamp; cumulus.LogMessage("Processing data for " + timestamp); var h = timestamp.Hour; // if outside rollover hour, rollover yet to be done if (h != rollHour) { rolloverdone = false; } // In rollover hour and rollover not yet done if (h == rollHour && !rolloverdone) { // do rollover cumulus.LogMessage("Day rollover " + timestamp.ToShortTimeString()); DayReset(timestamp); rolloverdone = true; } // Not in midnight hour, midnight rain yet to be done if (h != 0) { midnightraindone = false; } // In midnight hour and midnight rain (and sun) not yet done if (h == 0 && !midnightraindone) { ResetMidnightRain(timestamp); ResetSunshineHours(timestamp); ResetMidnightTemperatures(timestamp); midnightraindone = true; } // Pressure ============================================================= var alt = AltitudeM(cumulus.Altitude); var seaLevel = MeteoLib.GetSeaLevelPressure(alt, (double)historydata.StationPressure, (double)historydata.Temperature); DoPressure(ConvertPressMBToUser(seaLevel), timestamp); // Outdoor Humidity ===================================================== DoOutdoorHumidity((int)historydata.Humidity, timestamp); // Wind ================================================================= DoWind(ConvertWindMSToUser((double)historydata.WindGust), historydata.WindDirection, ConvertWindMSToUser((double)historydata.WindAverage), timestamp); // Outdoor Temperature ================================================== DoOutdoorTemp(ConvertTempCToUser((double)historydata.Temperature), timestamp); // add in 'archivePeriod' minutes worth of temperature to the temp samples tempsamplestoday += historydata.ReportInterval; TempTotalToday += OutdoorTemperature * historydata.ReportInterval; // update chill hours if (OutdoorTemperature < cumulus.ChillHourThreshold) { // add 1 minute to chill hours ChillHours += historydata.ReportInterval / 60.0; } double rainrate = (double)(ConvertRainMMToUser((double)historydata.Precipitation) * (60d / historydata.ReportInterval)); var newRain = Raincounter + ConvertRainMMToUser((double)historydata.Precipitation); cumulus.LogMessage( $"TempestDoRainHist: New Precip: {historydata.Precipitation}, Type: {historydata.PrecipType}, Rate: {rainrate}, LocalDayRain: {historydata.LocalDayRain}, LocalRainChecked: {historydata.LocalRainChecked}, FinalRainChecked: {historydata.FinalRainChecked}"); DoRain(newRain, rainrate, timestamp); cumulus.LogMessage( $"TempestDoRainHist: Total Precip for Day: {Raincounter}"); OutdoorDewpoint = ConvertTempCToUser(MeteoLib.DewPoint(ConvertUserTempToC(OutdoorTemperature), OutdoorHumidity)); CheckForDewpointHighLow(timestamp); // calculate wind chill if (ConvertUserWindToMS(WindAverage) < 1.5) { DoWindChill(OutdoorTemperature, timestamp); } else { // calculate wind chill from calibrated C temp and calibrated win in KPH DoWindChill( ConvertTempCToUser(MeteoLib.WindChill(ConvertUserTempToC(OutdoorTemperature), ConvertUserWindToKPH(WindAverage))), timestamp); } DoApparentTemp(timestamp); DoFeelsLike(timestamp); DoHumidex(timestamp); DoCloudBaseHeatIndex(timestamp); DoUV((double)historydata.UV, timestamp); DoSolarRad(historydata.SolarRadiation, timestamp); // add in archive period worth of sunshine, if sunny if (SolarRad > CurrentSolarMax * cumulus.SolarOptions.SunThreshold / 100 && SolarRad >= cumulus.SolarOptions.SolarMinimum) { SunshineHours += historydata.ReportInterval / 60.0; } LightValue = historydata.Illuminance; // add in 'following interval' minutes worth of wind speed to windrun cumulus.LogMessage("Windrun: " + WindAverage.ToString(cumulus.WindFormat) + cumulus.Units.WindText + " for " + historydata.ReportInterval + " minutes = " + (WindAverage * WindRunHourMult[cumulus.Units.Wind] * historydata.ReportInterval / 60.0).ToString(cumulus.WindRunFormat) + cumulus.Units.WindRunText); WindRunToday += WindAverage * WindRunHourMult[cumulus.Units.Wind] * historydata.ReportInterval / 60.0; // update heating/cooling degree days UpdateDegreeDays(historydata.ReportInterval); // update dominant wind bearing CalculateDominantWindBearing(Bearing, WindAverage, historydata.ReportInterval); CheckForWindrunHighLow(timestamp); bw?.ReportProgress((totalentries - datalist.Count) * 100 / totalentries, "processing"); //UpdateDatabase(timestamp.ToUniversalTime(), historydata.interval, false); cumulus.DoLogFile(timestamp, false); if (cumulus.StationOptions.LogExtraSensors) { cumulus.DoExtraLogFile(timestamp); } //AddRecentDataEntry(timestamp, WindAverage, RecentMaxGust, WindLatest, Bearing, AvgBearing, // OutdoorTemperature, WindChill, OutdoorDewpoint, HeatIndex, // OutdoorHumidity, Pressure, RainToday, SolarRad, UV, Raincounter, FeelsLike, Humidex); AddRecentDataWithAq(timestamp, WindAverage, RecentMaxGust, WindLatest, Bearing, AvgBearing, OutdoorTemperature, WindChill, OutdoorDewpoint, HeatIndex, OutdoorHumidity, Pressure, RainToday, SolarRad, UV, Raincounter, FeelsLike, Humidex, ApparentTemperature, IndoorTemperature, IndoorHumidity, CurrentSolarMax, RainRate); if (cumulus.StationOptions.CalculatedET && timestamp.Minute == 0) { // Start of a new hour, and we want to calculate ET in Cumulus CalculateEvaoptranspiration(timestamp); } DoTrendValues(timestamp); UpdatePressureTrendString(); UpdateStatusPanel(timestamp); cumulus.AddToWebServiceLists(timestamp); } ticks = Environment.TickCount - ticks; var rate = ((double)totalentries / ticks) * 1000; cumulus.LogMessage($"End processing history data. Rate: {rate:f2}/second"); cumulus.LogConsoleMessage($"Completed processing history data. {DateTime.Now.ToLongTimeString()}, Rate: {rate:f2}/second"); }
private void WeatherPacketReceived(WeatherPacket wp) { DateTime ts; if (wp != null) { switch (wp.MsgType) { case WeatherPacket.MessageType.Observation: cumulus.LogDebugMessage("Received an Observation message"); cumulus.LogDataMessage( string.Format($"Observation data - temp: {0}, hum: {1}, gust: {2}, spdvg: {3}, press: {4}, solar: {5}, UV: {6}, rain: {7}, batt: {8}", wp.Observation.Temperature, wp.Observation.Humidity, wp.Observation.WindGust, wp.Observation.WindAverage, wp.Observation.StationPressure, wp.Observation.SolarRadiation, wp.Observation.UV, wp.Observation.Precipitation, wp.Observation.BatteryVoltage ) ); ts = wp.Observation.Timestamp; var userTemp = ConvertTempCToUser(Convert.ToDouble(wp.Observation.Temperature)); DoOutdoorTemp(userTemp, ts); DoWind(ConvertWindMSToUser((double)wp.Observation.WindGust), wp.Observation.WindDirection, ConvertWindMSToUser((double)wp.Observation.WindAverage), ts); var alt = AltitudeM(cumulus.Altitude); var seaLevel = MeteoLib.GetSeaLevelPressure(alt, (double)wp.Observation.StationPressure, (double)wp.Observation.Temperature); DoPressure(ConvertPressMBToUser(seaLevel), ts); cumulus.LogDebugMessage( $"TempestPressure: Station:{wp.Observation.StationPressure} mb, Sea Level:{seaLevel} mb, Altitude:{alt}"); DoSolarRad(wp.Observation.SolarRadiation, ts); DoUV((double)wp.Observation.UV, ts); double rainrate = (double)(ConvertRainMMToUser((double)wp.Observation.Precipitation) * (60d / wp.Observation.ReportInterval)); var newRain = Raincounter + ConvertRainMMToUser((double)wp.Observation.Precipitation); cumulus.LogDebugMessage( $"TempestDoRain: New Precip: {wp.Observation.Precipitation}, Type: {wp.Observation.PrecipType}, Rate: {rainrate}"); DoRain(newRain, rainrate, ts); cumulus.LogDebugMessage( $"TempestDoRain: Total Precip for Day: {Raincounter}"); DoOutdoorHumidity((int)wp.Observation.Humidity, ts); OutdoorDewpoint = ConvertTempCToUser(MeteoLib.DewPoint(ConvertUserTempToC(OutdoorTemperature), OutdoorHumidity)); CheckForDewpointHighLow(ts); DoApparentTemp(ts); DoFeelsLike(ts); DoWindChill(userTemp, ts); DoHumidex(ts); DoCloudBaseHeatIndex(ts); UpdateStatusPanel(ts); UpdateMQTT(); DoForecast(string.Empty, false); cumulus.BatteryLowAlarm.Triggered = wp.Observation.BatteryVoltage <= 2.355M; break; case WeatherPacket.MessageType.RapidWind: cumulus.LogDebugMessage("Received a Rapid Wind message"); var rw = wp.RapidWind; cumulus.LogDataMessage($"Wind Data - speed: {rw.WindSpeed}, direction: {rw.WindDirection}"); DoWind(ConvertWindMSToUser((double)rw.WindSpeed), rw.WindDirection, ConvertWindMSToUser((double)rw.WindSpeed), rw.Timestamp); UpdateStatusPanel(rw.Timestamp); break; case WeatherPacket.MessageType.LightningStrike: cumulus.LogDebugMessage("Received a Lightning message"); LightningTime = wp.LightningStrike.Timestamp; LightningDistance = ConvertKmtoUserUnits(wp.LightningStrike.Distance); LightningStrikesToday++; cumulus.LogDebugMessage($"Lightning Detected: {wp.LightningStrike.Timestamp} - {wp.LightningStrike.Distance} km - {LightningStrikesToday} strikes today"); break; } } }