From 906d48dead6555b2d5c75811b1f026a60b0c14d9 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Wed, 17 May 2023 11:09:30 +0100 Subject: [PATCH 01/27] URL encode PWS passwords --- CumulusMX/Properties/AssemblyInfo.cs | 6 +++--- CumulusMX/WeatherStation.cs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CumulusMX/Properties/AssemblyInfo.cs b/CumulusMX/Properties/AssemblyInfo.cs index 144331ec..05682577 100644 --- a/CumulusMX/Properties/AssemblyInfo.cs +++ b/CumulusMX/Properties/AssemblyInfo.cs @@ -6,7 +6,7 @@ // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("Cumulus MX")] -[assembly: AssemblyDescription("Version 3.25.1 - Build 3244")] +[assembly: AssemblyDescription("Version 3.26.0 - Build 3245")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Cumulus MX")] @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("3.25.1.3244")] -[assembly: AssemblyFileVersion("3.25.1.3244")] +[assembly: AssemblyVersion("3.26.0.3245")] +[assembly: AssemblyFileVersion("3.26.0.3245")] diff --git a/CumulusMX/WeatherStation.cs b/CumulusMX/WeatherStation.cs index 341e350e..c4a974f6 100644 --- a/CumulusMX/WeatherStation.cs +++ b/CumulusMX/WeatherStation.cs @@ -10797,12 +10797,12 @@ public string GetPWSURL(out string pwstring, DateTime timestamp) { string dateUTC = timestamp.ToUniversalTime().ToString("yyyy'-'MM'-'dd'+'HH'%3A'mm'%3A'ss"); StringBuilder URL = new StringBuilder("http://www.pwsweather.com/pwsupdate/pwsupdate.php?ID=", 1024); + StringBuilder Data = new StringBuilder(1024); - pwstring = "&PASSWORD=" + cumulus.PWS.PW; + pwstring = "&PASSWORD=" + HttpUtility.UrlEncode(cumulus.PWS.PW); URL.Append(cumulus.PWS.ID + pwstring); URL.Append("&dateutc=" + dateUTC); - StringBuilder Data = new StringBuilder(1024); // send average speed and bearing Data.Append("&winddir=" + AvgBearing); From 1f7cb5299a837501297e43b4dde8de0deb04ca61 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Wed, 17 May 2023 11:10:36 +0100 Subject: [PATCH 02/27] Update libraries to current versions --- CumulusMX/CumulusMX.csproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CumulusMX/CumulusMX.csproj b/CumulusMX/CumulusMX.csproj index f41518f9..e77c6024 100644 --- a/CumulusMX/CumulusMX.csproj +++ b/CumulusMX/CumulusMX.csproj @@ -239,19 +239,19 @@ 2.1.0 - 3.6.0 + 4.0.0 - 4.1.4.563 + 4.2.0.706 - 2.2.5 + 2.2.6 2.2.5 - 6.7.0 + 6.8.0 2020.0.2 From c08479e1af18a553bd77b55fdb5d5f9d796416cb Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Thu, 18 May 2023 15:06:13 +0100 Subject: [PATCH 03/27] Solar values now stored as ints --- CumulusMX/AstroLib.cs | 20 ++++++++++---------- CumulusMX/Cumulus.cs | 6 +++--- CumulusMX/WeatherStation.cs | 23 +++++++++++++++-------- CumulusMX/webtags.cs | 4 ++-- Updates.txt | 25 +++++++++++++++++++++++++ 5 files changed, 55 insertions(+), 23 deletions(-) diff --git a/CumulusMX/AstroLib.cs b/CumulusMX/AstroLib.cs index cde6eb68..688e689f 100644 --- a/CumulusMX/AstroLib.cs +++ b/CumulusMX/AstroLib.cs @@ -4,7 +4,7 @@ namespace CumulusMX { internal class AstroLib { - public static double BrasSolar(double el, double erv, double nfac) + public static int BrasSolar(double el, double erv, double nfac) { // el solar elevation deg from horizon // erv distance from earth to sun in AU @@ -25,10 +25,10 @@ public static double BrasSolar(double el, double erv, double nfac) double al = 0.128 - (0.054 * Math.Log(m) / Math.Log(10)); // clear-sky solar radiation at earth surface on horizontal surface (W/m^2) - return i0 * Math.Exp(-nfac * al * m); + return (int) Math.Round(i0 * Math.Exp(-nfac * al * m)); } - public static double RyanStolzSolar(double el, double erv, double atc, double z) + public static int RyanStolzSolar(double el, double erv, double atc, double z) { // el solar elevation deg from horizon // erv distance from earth to sun in AU @@ -47,7 +47,7 @@ public static double RyanStolzSolar(double el, double erv, double atc, double z) double rsToa = 1360 * sinal / (erv * erv); // RS on the top of atmosphere - return rsToa * Math.Pow(atc, rm); //RS on the ground + return (int) Math.Round(rsToa * Math.Pow(atc, rm)); //RS on the ground } private static double DegToRad(double angle) @@ -60,8 +60,8 @@ private static double RadToDeg(double angle) return angle * (180.0 / Math.PI); } - public static double SolarMax(DateTime timestamp, double longitude, double latitude, double altitude, - out double solarelevation, SolarOptions options) + public static int SolarMax(DateTime timestamp, double longitude, double latitude, double altitude, + out double solarelevation, SolarOptions options) { double factor = 0; if (options.SolarCalc == 0) @@ -76,7 +76,7 @@ public static double SolarMax(DateTime timestamp, double longitude, double latit } - private static double SolarMax(DateTime timestamp, double longitude, double latitude, double altitude, + private static int SolarMax(DateTime timestamp, double longitude, double latitude, double altitude, out double solarelevation, double factor, int method) { DateTime utctime = timestamp.ToUniversalTime(); @@ -504,7 +504,7 @@ private static double calcObliquityCorrection(double t) double e0 = calcMeanObliquityOfEcliptic(t); double omega = 125.04 - 1934.136 * t; - + return e0 + 0.00256 * Math.Cos(DegToRad(omega)); } @@ -543,7 +543,7 @@ private static void CalculateSunPosition(DateTime dateTime, double latitude, dou //var solarNoonLst = (720.0 - 4 * longitude - eqOfTime + zone * 60.0) / 1440.0; //var sunriseTimeLst = solarNoonLst - haSunRise * 4 / 1440.0; //var sunsetTimeLst = solarNoonLst + haSunRise * 4 / 1440.0; - //var sunlightDurationMins = 8 * haSunRise; + //var sunlightDurationMins = 8 * haSunRise; var trueSolarTime = PutInRange(dateTime.TimeOfDay.TotalMinutes + eqOfTime + 4 * longitude - 60 * zone, 1440); var hourAngle = trueSolarTime / 4.0 < 0 ? trueSolarTime / 4.0 + 180 : trueSolarTime / 4.0 - 180; var solarZenithAngle = RadToDeg(Math.Acos(Math.Sin(DegToRad(latitude)) * Math.Sin(DegToRad(sunDec)) + Math.Cos(DegToRad(latitude)) * Math.Cos(DegToRad(sunDec)) * Math.Cos(DegToRad(hourAngle)))); @@ -636,7 +636,7 @@ public static void CalculateSunPosition(DateTime dateTime, double latitude, doub Math.Sin(latitude * Deg2Rad) * Math.Sin(declination) + Math.Cos(latitude * Deg2Rad) * - Math.Cos(declination) * + Math.Cos(declination) * Math.Cos(hourAngle) ); diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index 8cbe9786..0944c56e 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -7798,7 +7798,7 @@ public async void DoLogFile(DateTime timestamp, bool live) sb.Append(station.ET.ToString(ETFormat) + ListSeparator); sb.Append(station.AnnualETTotal.ToString(ETFormat) + ListSeparator); sb.Append(station.ApparentTemperature.ToString(TempFormat) + ListSeparator); - sb.Append(Math.Round(station.CurrentSolarMax) + ListSeparator); + sb.Append(station.CurrentSolarMax + ListSeparator); sb.Append(station.SunshineHours.ToString(SunFormat) + ListSeparator); sb.Append(station.Bearing + ListSeparator); sb.Append(station.RG11RainToday.ToString(RainFormat) + ListSeparator); @@ -7865,7 +7865,7 @@ public async void DoLogFile(DateTime timestamp, bool live) values.Append(station.ET.ToString(ETFormat, InvC) + ","); values.Append(station.AnnualETTotal.ToString(ETFormat, InvC) + ","); values.Append(station.ApparentTemperature.ToString(TempFormat, InvC) + ","); - values.Append((Math.Round(station.CurrentSolarMax)) + ","); + values.Append(station.CurrentSolarMax + ","); values.Append(station.SunshineHours.ToString(SunFormat, InvC) + ","); values.Append(station.Bearing + ","); values.Append(station.RG11RainToday.ToString(RainFormat, InvC) + ","); @@ -11640,7 +11640,7 @@ public void MySqlRealtimeFile(int cycle, bool live, DateTime? logdate = null) values.Append((CloudBaseInFeet ? "ft" : "m") + "',"); values.Append(station.ApparentTemperature.ToString(TempFormat, InvC) + ','); values.Append(station.SunshineHours.ToString(SunFormat, InvC) + ','); - values.Append(((int)Math.Round(station.CurrentSolarMax)).ToString() + ",'"); + values.Append(station.CurrentSolarMax + ",'"); values.Append((station.IsSunny ? "1" : "0") + "',"); values.Append(station.FeelsLike.ToString(TempFormat, InvC)); values.Append(')'); diff --git a/CumulusMX/WeatherStation.cs b/CumulusMX/WeatherStation.cs index c4a974f6..5b61e9a7 100644 --- a/CumulusMX/WeatherStation.cs +++ b/CumulusMX/WeatherStation.cs @@ -262,7 +262,7 @@ public struct DailyHighLow public DateTime HighDewPointTime; public double LowDewPoint; public DateTime LowDewPointTime; - public double HighSolar; + public int HighSolar; public DateTime HighSolarTime; public double HighUv; public DateTime HighUvTime; @@ -670,7 +670,7 @@ public void ReadTodayFile() cumulus.NOAAconf.LatestYearReport = ini.GetValue("NOAA", "LatestYearlyReport", ""); // Solar - HiLoToday.HighSolar = ini.GetValue("Solar", "HighSolarRad", 0.0); + HiLoToday.HighSolar = ini.GetValue("Solar", "HighSolarRad", 0); HiLoToday.HighSolarTime = ini.GetValue("Solar", "HighSolarRadTime", todayDate); HiLoToday.HighUv = ini.GetValue("Solar", "HighUV", 0.0); HiLoToday.HighUvTime = ini.GetValue("Solar", "HighUVTime", metoTodayDate); @@ -1015,7 +1015,7 @@ private int StartOfMonthOADate() /// /// Solar Radiation in W/m2 /// - public double SolarRad { get; set; } = 0; + public int SolarRad { get; set; } = 0; /// /// UV index @@ -1403,7 +1403,7 @@ public void UpdateDegreeDays(int interval) public double StartOfDaySunHourCounter { get; set; } - public double CurrentSolarMax { get; set; } + public int CurrentSolarMax { get; set; } public double RG11RainToday { get; set; } @@ -5667,7 +5667,14 @@ public void DoUV(double value, DateTime timestamp) public void DoSolarRad(int value, DateTime timestamp) { - SolarRad = cumulus.Calib.Solar.Calibrate(value); + try + { + SolarRad = (int) Math.Round(cumulus.Calib.Solar.Calibrate(value)); + } + catch + { + SolarRad = 0; + } if (SolarRad < 0) SolarRad = 0; @@ -6031,7 +6038,7 @@ public void ReadYesterdayFile() HiLoYest.HighDewPoint = ini.GetValue("Dewpoint", "High", 0.0); HiLoYest.HighDewPointTime = ini.GetValue("Dewpoint", "HTime", DateTime.MinValue); // Solar - HiLoYest.HighSolar = ini.GetValue("Solar", "HighSolarRad", 0.0); + HiLoYest.HighSolar = ini.GetValue("Solar", "HighSolarRad", 0); HiLoYest.HighSolarTime = ini.GetValue("Solar", "HighSolarRadTime", DateTime.MinValue); HiLoYest.HighUv = ini.GetValue("Solar", "HighUV", 0.0); HiLoYest.HighUvTime = ini.GetValue("Solar", "HighUVTime", DateTime.MinValue); @@ -10063,7 +10070,7 @@ public string GetWCloudURL(out string pwstring, DateTime timestamp) // solar if (cumulus.WCloud.SendSolar) { - sb.Append("&solarrad=" + (int)Math.Round(SolarRad * 10)); + sb.Append("&solarrad=" + SolarRad * 10); } // uv @@ -13844,7 +13851,7 @@ internal string GetCurrentData() HiLoToday.LowWindChillTime.ToString(cumulus.ProgramOptions.TimeFormat), (int)SolarRad, (int)HiLoToday.HighSolar, HiLoToday.HighSolarTime.ToString(cumulus.ProgramOptions.TimeFormat), UV, HiLoToday.HighUv, HiLoToday.HighUvTime.ToString(cumulus.ProgramOptions.TimeFormat), forecaststr, getTimeString(cumulus.SunRiseTime, cumulus.ProgramOptions.TimeFormat), getTimeString(cumulus.SunSetTime, cumulus.ProgramOptions.TimeFormat), getTimeString(cumulus.MoonRiseTime, cumulus.ProgramOptions.TimeFormat), getTimeString(cumulus.MoonSetTime, cumulus.ProgramOptions.TimeFormat), HiLoToday.HighHeatIndex, HiLoToday.HighHeatIndexTime.ToString(cumulus.ProgramOptions.TimeFormat), HiLoToday.HighAppTemp, - HiLoToday.LowAppTemp, HiLoToday.HighAppTempTime.ToString(cumulus.ProgramOptions.TimeFormat), HiLoToday.LowAppTempTime.ToString(cumulus.ProgramOptions.TimeFormat), (int)Math.Round(CurrentSolarMax), + HiLoToday.LowAppTemp, HiLoToday.HighAppTempTime.ToString(cumulus.ProgramOptions.TimeFormat), HiLoToday.LowAppTempTime.ToString(cumulus.ProgramOptions.TimeFormat), CurrentSolarMax, AllTime.HighPress.Val, AllTime.LowPress.Val, SunshineHours, CompassPoint(DominantWindBearing), LastRainTip, HiLoToday.HighHourlyRain, HiLoToday.HighHourlyRainTime.ToString(cumulus.ProgramOptions.TimeFormat), "F" + cumulus.Beaufort(HiLoToday.HighWind), "F" + cumulus.Beaufort(WindAverage), cumulus.BeaufortDesc(WindAverage), LastDataReadTimestamp.ToString(cumulus.ProgramOptions.TimeFormatLong), DataStopped, StormRain, stormRainStart, CloudBase, cumulus.CloudBaseInFeet ? "ft" : "m", RainLast24Hour, diff --git a/CumulusMX/webtags.cs b/CumulusMX/webtags.cs index d2fdac59..0d0d08e3 100644 --- a/CumulusMX/webtags.cs +++ b/CumulusMX/webtags.cs @@ -3485,12 +3485,12 @@ private string TagUv(Dictionary tagParams) private string TagSolarRad(Dictionary tagParams) { - return ((int) station.SolarRad).ToString(); + return station.SolarRad.ToString(); } private string TagCurrentSolarMax(Dictionary tagParams) { - return ((int) Math.Round(station.CurrentSolarMax)).ToString(); + return station.CurrentSolarMax.ToString(); } private string TagSunshineHours(Dictionary tagParams) diff --git a/Updates.txt b/Updates.txt index b228ad93..b4fbffc2 100644 --- a/Updates.txt +++ b/Updates.txt @@ -1,3 +1,28 @@ +3.26.0 - b3245 +—————————————— +New +- MQTT has a new behaviour - Only update a topic if the data has changed + - If you add a new property called "doNotTriggerOnTags" to a topic, you can specify a list of web tokens. Adding this property with at least one entry triggers the new behaviour. + The web tokens in the list are excluded from the comparison process, so for instance if you include a timestamp in your topic, you can exclude this from the change detection. + For example: + { + "topic": "CumulusMX/TempUpdate", + "data": "\"time\":\"<#timehhmmss>\",\"temp\":<#temp rc=y>", + "retain": false, + "doNotTriggerOnTags": "timehhmmss" + } + Which now will only send a new MQTT message when CMX first starts, then only when the "#temp" value changes. + +Changed +- Various third party libraries updated to current versions + - MailKit, MQTTnet, MySqlConnector, ServiceStack + +Fixed +- PWS passwords are now URL encoded +- Solar irradiation and theoretical solar are now stored as integers everywhere + + + 3.25.1 - b3244 —————————————— New From 0e0d46b514b64a59b68893753f925663d748aa2f Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Thu, 18 May 2023 16:25:33 +0100 Subject: [PATCH 04/27] enable .pdb creation for release builds --- CumulusMX/CumulusMX.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CumulusMX/CumulusMX.csproj b/CumulusMX/CumulusMX.csproj index e77c6024..8bd3b8dc 100644 --- a/CumulusMX/CumulusMX.csproj +++ b/CumulusMX/CumulusMX.csproj @@ -49,14 +49,14 @@ AnyCPU - none + pdbonly true bin\Release\ TRACE prompt 4 ".pdb"="" - false + true false From e6cb6271a211ab3f67365d4230304deaadbf399a Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Thu, 18 May 2023 17:01:41 +0100 Subject: [PATCH 05/27] Update OS version output to log --- CumulusMX/Cumulus.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index 0944c56e..0cdd8ad6 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -705,7 +705,7 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) MethodInfo displayName = type.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static); if (displayName != null) - LogMessage("Mono version: " + displayName.Invoke(null, null)); + LogMessage("Mono version : " + displayName.Invoke(null, null)); } // restrict the threadpool size - for Mono which does not seem to have very good pool management! @@ -715,9 +715,16 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) Platform = IsOSX ? "Mac OS X" : Environment.OSVersion.Platform.ToString(); - LogMessage("Platform: " + Platform); + LogMessage("Platform : " + Platform); - LogMessage("OS version: " + Environment.OSVersion); + try + { + LogMessage("OS Description : " + RuntimeInformation.OSDescription); + } + catch + { + LogMessage("OS Version : " + Environment.OSVersion + " (possibly not accurate)"); + } LogMessage($"Current culture: {CultureInfo.CurrentCulture.DisplayName} [{CultureInfo.CurrentCulture.Name}]"); From 807ba79ca57589c7404f20c365cdf0f622f60dd4 Mon Sep 17 00:00:00 2001 From: mcrossley Date: Mon, 22 May 2023 10:40:30 +0100 Subject: [PATCH 06/27] Fix end of day files not being processed --- CumulusMX/Cumulus.cs | 13 +++++++++++-- CumulusMX/CumulusMX.csproj | 8 ++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index d17a7c2f..36c5c94d 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -12184,11 +12184,20 @@ public void DoExtraEndOfDayFiles() LogDebugMessage($"EOD: Copying extra file {uploadfile} to {remotefile}"); try { - File.Copy(uploadfile, remotefile, true); + if (ExtraFiles[i].process) + { + var data = ProcessTemplateFile2String(uploadfile, false, ExtraFiles[i].UTF8); + File.WriteAllText(remotefile, data); + } + else + { + // just copy the file + File.Copy(uploadfile, remotefile, true); + } } catch (Exception ex) { - LogDebugMessage($"EOD: Error copying extra file {uploadfile} to {remotefile}: {ex.Message}"); + LogExceptionMessage(ex, $"EOD: Error copying extra file {uploadfile} to {remotefile}"); } //LogDebugMessage("Finished copying extra file " + uploadfile); } diff --git a/CumulusMX/CumulusMX.csproj b/CumulusMX/CumulusMX.csproj index f41518f9..e77c6024 100644 --- a/CumulusMX/CumulusMX.csproj +++ b/CumulusMX/CumulusMX.csproj @@ -239,19 +239,19 @@ 2.1.0 - 3.6.0 + 4.0.0 - 4.1.4.563 + 4.2.0.706 - 2.2.5 + 2.2.6 2.2.5 - 6.7.0 + 6.8.0 2020.0.2 From 3e173b55a732e93ad40fe8546e2656db8021da23 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Mon, 22 May 2023 10:41:56 +0100 Subject: [PATCH 07/27] updates.txt --- Updates.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Updates.txt b/Updates.txt index b4fbffc2..3c1e2dc0 100644 --- a/Updates.txt +++ b/Updates.txt @@ -20,7 +20,7 @@ Changed Fixed - PWS passwords are now URL encoded - Solar irradiation and theoretical solar are now stored as integers everywhere - +- Extra end of day files not being processed on copy 3.25.1 - b3244 From 23262e0f69a76c6181c6ac2d343d42c5eef4a698 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Mon, 22 May 2023 19:10:56 +0100 Subject: [PATCH 08/27] Davis VP2 stations creating incorrect values for Wind Run and Chill Hours if some logger data is missing --- CumulusMX/DavisStation.cs | 16 +++++++++++++--- Updates.txt | 1 + 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CumulusMX/DavisStation.cs b/CumulusMX/DavisStation.cs index d2068e99..68e60fb5 100644 --- a/CumulusMX/DavisStation.cs +++ b/CumulusMX/DavisStation.cs @@ -824,7 +824,7 @@ private void bw_DoWork(object sender, DoWorkEventArgs e) { } - private int calculateCRC(byte[] data) + private static int calculateCRC(byte[] data) { ushort crc = 0; ushort[] crcTable = @@ -871,7 +871,7 @@ private int calculateCRC(byte[] data) return crc; } - private bool CrcOk(byte[] data) + private static bool CrcOk(byte[] data) { return (calculateCRC(data) == 0); } @@ -2047,6 +2047,7 @@ private void GetArchiveData() const int pageSize = 267; const int recordSize = 52; bool ack; + bool starting = true; NetworkStream stream = null; @@ -2428,7 +2429,16 @@ private void GetArchiveData() midnightraindone = true; } - int interval = (int)(timestamp - lastDataReadTime).TotalMinutes; + int interval; + if (starting && timestamp > nextLoggerTime) + { + interval = loggerInterval; + starting = false; + } + else + { + interval = (int) (timestamp - lastDataReadTime).TotalMinutes; + } if ((archiveData.InsideTemperature > -200) && (archiveData.InsideTemperature < 300)) { diff --git a/Updates.txt b/Updates.txt index 3c1e2dc0..109cd313 100644 --- a/Updates.txt +++ b/Updates.txt @@ -21,6 +21,7 @@ Fixed - PWS passwords are now URL encoded - Solar irradiation and theoretical solar are now stored as integers everywhere - Extra end of day files not being processed on copy +- Davis VP2 stations creating incorrect values for Wind Run and Chill Hours if some logger data is missing 3.25.1 - b3244 From 9c67790ea03db858a8dcee7285866c1bbd46324a Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Tue, 23 May 2023 10:03:23 +0100 Subject: [PATCH 09/27] Revert forcing Tempest station to make MX calculate average wind speeds --- CumulusMX/TempestStation.cs | 3 --- Updates.txt | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/CumulusMX/TempestStation.cs b/CumulusMX/TempestStation.cs index fb9a5e98..46bd5741 100644 --- a/CumulusMX/TempestStation.cs +++ b/CumulusMX/TempestStation.cs @@ -28,9 +28,6 @@ public TempestStation(Cumulus cumulus) : base(cumulus) // Tempest does not provide wind chill cumulus.StationOptions.CalculatedWC = true; - // Tempest does not provide average wind speeds - cumulus.StationOptions.CalcuateAverageWindSpeed = true; - LoadLastHoursFromDataLogs(cumulus.LastUpdateTime); Task.Run(getAndProcessHistoryData);// grab old data, then start the station diff --git a/Updates.txt b/Updates.txt index 109cd313..bc32b01b 100644 --- a/Updates.txt +++ b/Updates.txt @@ -22,6 +22,7 @@ Fixed - Solar irradiation and theoretical solar are now stored as integers everywhere - Extra end of day files not being processed on copy - Davis VP2 stations creating incorrect values for Wind Run and Chill Hours if some logger data is missing +- Revert: Tempest station now forces MX to calculate the average wind speed 3.25.1 - b3244 From 156c94569f675425e822c264407dacd6cb890496 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Tue, 23 May 2023 10:27:34 +0100 Subject: [PATCH 10/27] Revert "Revert forcing Tempest station to make MX calculate average wind speeds" This reverts commit 9c67790ea03db858a8dcee7285866c1bbd46324a. --- CumulusMX/TempestStation.cs | 3 +++ Updates.txt | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CumulusMX/TempestStation.cs b/CumulusMX/TempestStation.cs index 46bd5741..fb9a5e98 100644 --- a/CumulusMX/TempestStation.cs +++ b/CumulusMX/TempestStation.cs @@ -28,6 +28,9 @@ public TempestStation(Cumulus cumulus) : base(cumulus) // Tempest does not provide wind chill cumulus.StationOptions.CalculatedWC = true; + // Tempest does not provide average wind speeds + cumulus.StationOptions.CalcuateAverageWindSpeed = true; + LoadLastHoursFromDataLogs(cumulus.LastUpdateTime); Task.Run(getAndProcessHistoryData);// grab old data, then start the station diff --git a/Updates.txt b/Updates.txt index bc32b01b..109cd313 100644 --- a/Updates.txt +++ b/Updates.txt @@ -22,7 +22,6 @@ Fixed - Solar irradiation and theoretical solar are now stored as integers everywhere - Extra end of day files not being processed on copy - Davis VP2 stations creating incorrect values for Wind Run and Chill Hours if some logger data is missing -- Revert: Tempest station now forces MX to calculate the average wind speed 3.25.1 - b3244 From 16b25dd2478b195e44517b3d4025f4f6c08fc060 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Tue, 23 May 2023 18:32:57 +0100 Subject: [PATCH 11/27] Instromet station now forces MX to calculate the average wind speed --- CumulusMX/ImetStation.cs | 9 +++++++++ Updates.txt | 2 ++ 2 files changed, 11 insertions(+) diff --git a/CumulusMX/ImetStation.cs b/CumulusMX/ImetStation.cs index 79bc13f7..56b6990a 100644 --- a/CumulusMX/ImetStation.cs +++ b/CumulusMX/ImetStation.cs @@ -29,6 +29,9 @@ public ImetStation(Cumulus cumulus) : base(cumulus) calculaterainrate = true; + // Imet does not provide average wind speeds + cumulus.StationOptions.CalcuateAverageWindSpeed = true; + // Change the default dps for rain and sunshine from 1 to 2 for IMet stations cumulus.RainDPlaces = cumulus.SunshineDPlaces = 2; cumulus.RainDPlaceDefaults[0] = 2; // mm @@ -415,6 +418,9 @@ public override void startReadingHistoryData() cumulus.LogConsoleMessage("Start reading history data..."); //lastArchiveTimeUTC = getLastArchiveTime(); + // use the wind speeds averages from the logger data + cumulus.StationOptions.CalcuateAverageWindSpeed = false; + LoadLastHoursFromDataLogs(cumulus.LastUpdateTime); bw = new BackgroundWorker(); @@ -441,6 +447,9 @@ private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) //histprog.Close(); //mainWindow.FillLastHourGraphData(); + // normal running + cumulus.StationOptions.CalcuateAverageWindSpeed = true; + cumulus.NormalRunning = true; cumulus.LogMessage("Archive reading thread completed"); DoDayResetIfNeeded(); diff --git a/Updates.txt b/Updates.txt index 109cd313..a367d75d 100644 --- a/Updates.txt +++ b/Updates.txt @@ -22,6 +22,8 @@ Fixed - Solar irradiation and theoretical solar are now stored as integers everywhere - Extra end of day files not being processed on copy - Davis VP2 stations creating incorrect values for Wind Run and Chill Hours if some logger data is missing +- Instromet station now forces MX to calculate the average wind speed + 3.25.1 - b3244 From 3a5f931e4cfacc9f594767e417baae6bd1555830 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Thu, 25 May 2023 16:51:03 +0100 Subject: [PATCH 12/27] Fix FTP logging errors when FTP logging is already enabled at start-up --- CumulusMX/Cumulus.cs | 16 +++++++++++----- Updates.txt | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index fa881ee3..9a55c4be 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -680,11 +680,6 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) Trace.Listeners.Add(myTextListener); Trace.AutoFlush = true; - if (FtpOptions.Logging) - { - CreateFtpLogFile(ftpLogfile); - } - // Read the configuration file LogMessage(" ========================== Cumulus MX starting =========================="); @@ -1047,9 +1042,16 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) CheckForSingleInstance(boolWindows); if (FtpOptions.FtpMode == FtpProtocols.PHP) + { LogMessage("Maximum concurrent PHP Uploads = " + FtpOptions.MaxConcurrentUploads); + } uploadCountLimitSemaphoreSlim = new SemaphoreSlim(FtpOptions.MaxConcurrentUploads); + if (FtpOptions.Logging) + { + CreateFtpLogFile(ftpLogfile); + } + ListSeparator = CultureInfo.CurrentCulture.TextInfo.ListSeparator; DecimalSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator; @@ -11376,7 +11378,11 @@ public void LogFluentFtpMessage(FtpTraceLevel level, string message) } catch (Exception ex) { + LogExceptionMessage(ex, $"LogFluentFtpMessage: Error"); + // Let's try closing and the existing log file and reopening LogDebugMessage($"LogFluentFtpMessage: Error = {ex.Message}"); + ftpLogfile = RemoveOldDiagsFiles("FTP"); + CreateFtpLogFile(ftpLogfile); } } } diff --git a/Updates.txt b/Updates.txt index a367d75d..845aa780 100644 --- a/Updates.txt +++ b/Updates.txt @@ -23,7 +23,7 @@ Fixed - Extra end of day files not being processed on copy - Davis VP2 stations creating incorrect values for Wind Run and Chill Hours if some logger data is missing - Instromet station now forces MX to calculate the average wind speed - +- FTP logging errors when FTP logging is already enabled at start-up 3.25.1 - b3244 From 66f28e200223389fb51d9afd5239b2aa0df24751 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Thu, 1 Jun 2023 10:39:07 +0100 Subject: [PATCH 13/27] Change PHP upload to send a text/plain content header --- CumulusMX/Cumulus.cs | 13 +++++++------ CumulusMX/DavisWllStation.cs | 6 ++---- Updates.txt | 3 ++- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index 9a55c4be..c0c691b9 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -11238,7 +11238,7 @@ private async Task UploadString(HttpClient httpclient, bool incremental, s // Compress? if supported and payload exceeds 500 bytes if (data.Length < 500 || FtpOptions.PhpCompression == "none") { - request.Content = new StringContent(data, encoding, "application/octet-stream"); + request.Content = new StringContent(data, encoding, "text/plain"); } else { @@ -11267,6 +11267,7 @@ private async Task UploadString(HttpClient httpclient, bool incremental, s outStream = new MemoryStream(compressed); streamContent = new StreamContent(outStream); + streamContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("text/plain"); streamContent.Headers.Add("Content-Encoding", FtpOptions.PhpCompression); streamContent.Headers.ContentLength = outStream.Length; @@ -11289,13 +11290,13 @@ private async Task UploadString(HttpClient httpclient, bool incremental, s LogDataMessage($"PHP[{cycleStr}]: Upload to {remotefile}: Response text follows:\n{responseBodyAsText}"); } - if (outStream != null) - outStream.Dispose(); + if (outStream != null) + outStream.Dispose(); - if (streamContent != null) - streamContent.Dispose(); + if (streamContent != null) + streamContent.Dispose(); - return response.StatusCode == HttpStatusCode.OK; + return response.StatusCode == HttpStatusCode.OK; } } } diff --git a/CumulusMX/DavisWllStation.cs b/CumulusMX/DavisWllStation.cs index 2b5a8396..36e7265a 100644 --- a/CumulusMX/DavisWllStation.cs +++ b/CumulusMX/DavisWllStation.cs @@ -3,10 +3,8 @@ using System.Collections.Generic; using System.ComponentModel; using System.Globalization; -using System.IO.Ports; using System.Linq; using System.Net; -using System.Net.Http; using System.Net.Sockets; using System.Reflection; using System.Text; @@ -30,7 +28,7 @@ internal class DavisWllStation : WeatherStation private readonly object threadSafer = new object(); private static readonly SemaphoreSlim WebReq = new SemaphoreSlim(1, 1); private bool startupDayResetIfRequired = true; - private bool savedUseSpeedForAvgCalc; + //private bool savedUseSpeedForAvgCalc; private bool savedCalculatePeakGust; private int maxArchiveRuns = 1; private bool broadcastReceived; @@ -41,7 +39,7 @@ internal class DavisWllStation : WeatherStation private readonly AutoResetEvent bwDoneEvent = new AutoResetEvent(false); private readonly List sensorList = new List(); private readonly bool useWeatherLinkDotCom = true; - private readonly bool checkWllGustValues; + //private readonly bool checkWllGustValues; public DavisWllStation(Cumulus cumulus) : base(cumulus) { diff --git a/Updates.txt b/Updates.txt index 378923c4..79c5c207 100644 --- a/Updates.txt +++ b/Updates.txt @@ -1,4 +1,4 @@ -3.26.0 - b3245 +3.26.0 - b3246 —————————————— New - MQTT has a new behaviour - Only update a topic if the data has changed @@ -16,6 +16,7 @@ New Changed - Various third party libraries updated to current versions - MailKit, MQTTnet, MySqlConnector, ServiceStack +- PHP upload now sends a text/plain content header Fixed - PWS passwords are now URL encoded From 9be0c5f0c9a133aece659f8cea568ed308604b56 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Thu, 1 Jun 2023 15:24:10 +0100 Subject: [PATCH 14/27] Davis WLL and Airlink now use the new simplified access method to weatherlink.com V2 API --- CumulusMX/Cumulus.cs | 8 -- CumulusMX/DavisAirLink.cs | 170 +++++++------------------------ CumulusMX/DavisWllStation.cs | 176 +++++++-------------------------- CumulusMX/WeatherLinkDotCom.cs | 17 ---- CumulusMX/WeatherStation.cs | 2 +- Updates.txt | 1 + 6 files changed, 72 insertions(+), 302 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index c0c691b9..b08af009 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -2143,14 +2143,6 @@ private void RG11StateChange(object sender, SerialPinChangedEventArgs e) } } - private void APRSTimerTick(object sender, ElapsedEventArgs e) - { - if (!string.IsNullOrEmpty(APRS.ID)) - { - station.UpdateAPRS(); - } - } - private void WebTimerTick(object sender, ElapsedEventArgs e) { if (station.DataStopped) diff --git a/CumulusMX/DavisAirLink.cs b/CumulusMX/DavisAirLink.cs index 44c2eac9..91b3c563 100644 --- a/CumulusMX/DavisAirLink.cs +++ b/CumulusMX/DavisAirLink.cs @@ -11,6 +11,7 @@ using ServiceStack; using Swan; using System.Threading.Tasks; +using ServiceStack.Text; namespace CumulusMX { @@ -637,43 +638,12 @@ private void GetWlHistoricData() cumulus.LogConsoleMessage($"Downloading Historic Data from WL.com from: {airLinkLastUpdateTime:s} to: {Utils.FromUnixTime(endTime):s}"); cumulus.LogMessage($"GetWlHistoricData: Downloading Historic Data from WL.com from: {airLinkLastUpdateTime:s} to: {Utils.FromUnixTime(endTime):s}"); - SortedDictionary parameters = new SortedDictionary - { - { "api-key", apiKey }, - { "station-id", stationId.ToString() }, - { "t", unixDateTime.ToString() }, - { "start-timestamp", startTime.ToString() }, - { "end-timestamp", endTime.ToString() } - }; - - StringBuilder dataStringBuilder = new StringBuilder(); - foreach (KeyValuePair entry in parameters) - { - dataStringBuilder.Append(entry.Key); - dataStringBuilder.Append(entry.Value); - } - - string data = dataStringBuilder.ToString(); + StringBuilder historicUrl = new StringBuilder("https://api.weatherlink.com/v2/historic/" + stationId); + historicUrl.Append("?api-key=" + apiKey); + historicUrl.Append("&start-timestamp=" + startTime.ToString()); + historicUrl.Append("&end-timestamp" + endTime.ToString()); - string apiSignature = WlDotCom.CalculateApiSignature(apiSecret, data); - - parameters.Remove("station-id"); - parameters.Add("api-signature", apiSignature); - - StringBuilder historicUrl = new StringBuilder(); - historicUrl.Append("https://api.weatherlink.com/v2/historic/" + stationId + "?"); - foreach (KeyValuePair entry in parameters) - { - historicUrl.Append(entry.Key); - historicUrl.Append('='); - historicUrl.Append(entry.Value); - historicUrl.Append('&'); - } - // remove the trailing "&" - historicUrl.Remove(historicUrl.Length - 1, 1); - - string logUrl = historicUrl.ToString().Replace(apiKey, "<>"); - cumulus.LogDebugMessage($"GetWlHistoricData: WeatherLink URL = {logUrl}"); + cumulus.LogDebugMessage($"GetWlHistoricData: WeatherLink URL = {historicUrl.ToString().Replace(apiKey, "API_KEY")}"); station.lastDataReadTime = airLinkLastUpdateTime; WlHistory histObj; @@ -686,8 +656,11 @@ private void GetWlHistoricData() string responseBody; int responseCode; + var request = new HttpRequestMessage(HttpMethod.Get, historicUrl.ToString()); + request.Headers.Add("X-Api-Secret", cumulus.WllApiSecret); + // we want to do this synchronously, so .Result - using (var response = Cumulus.MyHttpClient.GetAsync(historicUrl.ToString()).Result) + using (var response = Cumulus.MyHttpClient.SendAsync(request).Result) { responseBody = response.Content.ReadAsStringAsync().Result; responseCode = (int)response.StatusCode; @@ -1079,51 +1052,23 @@ private void GetWlHistoricHealth() cumulus.LogDebugMessage($"AirLinkHealth: Downloading the historic record from WL.com from: {Utils.FromUnixTime(startTime):s} to: {Utils.FromUnixTime(endTime):s}"); - SortedDictionary parameters = new SortedDictionary - { - { "api-key", apiKey }, - { "station-id", stationId.ToString() }, - { "t", unixDateTime.ToString() }, - { "start-timestamp", startTime.ToString() }, - { "end-timestamp", endTime.ToString() } - }; - - StringBuilder dataStringBuilder = new StringBuilder(); - foreach (KeyValuePair entry in parameters) - { - dataStringBuilder.Append(entry.Key); - dataStringBuilder.Append(entry.Value); - } - - string data = dataStringBuilder.ToString(); - - var apiSignature = WlDotCom.CalculateApiSignature(apiSecret, data); - - parameters.Remove("station-id"); - parameters.Add("api-signature", apiSignature); - - StringBuilder historicUrl = new StringBuilder(); - historicUrl.Append("https://api.weatherlink.com/v2/historic/" + stationId + "?"); - foreach (KeyValuePair entry in parameters) - { - historicUrl.Append(entry.Key); - historicUrl.Append('='); - historicUrl.Append(entry.Value); - historicUrl.Append('&'); - } - // remove the trailing "&" - historicUrl.Remove(historicUrl.Length - 1, 1); + StringBuilder historicUrl = new StringBuilder("https://api.weatherlink.com/v2/historic/" + stationId); + historicUrl.Append("?api-key=" + apiKey); + historicUrl.Append("&start-timestamp=" + startTime.ToString()); + historicUrl.Append("&end-timestamp" + endTime.ToString()); - var logUrl = historicUrl.ToString().Replace(apiKey, "<>"); - cumulus.LogDebugMessage($"AirLinkHealth: WeatherLink URL = {logUrl}"); + cumulus.LogDebugMessage($"AirLinkHealth: WeatherLink URL = {historicUrl.ToString().Replace(apiKey, "API_KEY")}"); try { string responseBody; int responseCode; + var request = new HttpRequestMessage(HttpMethod.Get, historicUrl.ToString()); + request.Headers.Add("X-Api-Secret", apiSecret); + // we want to do this synchronously, so .Result - using (var response = Cumulus.MyHttpClient.GetAsync(historicUrl.ToString()).Result) + using (var response = Cumulus.MyHttpClient.SendAsync(request).Result) { responseBody = response.Content.ReadAsStringAsync().Result; responseCode = (int)response.StatusCode; @@ -1356,39 +1301,20 @@ private bool GetAvailableStationIds() { "t", unixDateTime.ToString() } }; - StringBuilder dataStringBuilder = new StringBuilder(); - foreach (KeyValuePair entry in parameters) - { - dataStringBuilder.Append(entry.Key); - dataStringBuilder.Append(entry.Value); - } - string header = dataStringBuilder.ToString(); - - var apiSignature = WlDotCom.CalculateApiSignature(cumulus.AirLinkApiSecret, header); - parameters.Add("api-signature", apiSignature); - - StringBuilder stationsUrl = new StringBuilder(); - stationsUrl.Append("https://api.weatherlink.com/v2/stations?"); - foreach (KeyValuePair entry in parameters) - { - stationsUrl.Append(entry.Key); - stationsUrl.Append('='); - stationsUrl.Append(entry.Value); - stationsUrl.Append('&'); - } - // remove the trailing "&" - stationsUrl.Remove(stationsUrl.Length - 1, 1); + var stationsUrl = "https://api.weatherlink.com/v2/stations?api-key=" + cumulus.AirLinkApiKey; - var logUrl = stationsUrl.ToString().Replace(cumulus.AirLinkApiKey, "<>"); - cumulus.LogDebugMessage($"WeatherLink Stations URL = {logUrl}"); + cumulus.LogDebugMessage($"WeatherLink Stations URL = {stationsUrl.ToString().Replace(cumulus.AirLinkApiKey, "API_KEY")}"); try { string responseBody; int responseCode; - // We want to do this synchronously - using (var response = Cumulus.MyHttpClient.GetAsync(stationsUrl.ToString()).Result) + var request = new HttpRequestMessage(HttpMethod.Get, stationsUrl); + request.Headers.Add("X-Api-Secret", cumulus.AirLinkApiSecret); + + // we want to do this synchronously, so .Result + using (var response = Cumulus.MyHttpClient.SendAsync(request).Result) { responseBody = response.Content.ReadAsStringAsync().Result; responseCode = (int)response.StatusCode; @@ -1459,54 +1385,26 @@ private void GetAvailableSensors() return; } - apiKey = cumulus.AirLinkApiKey; - apiSecret = cumulus.AirLinkApiSecret; - if ((indoor && cumulus.AirLinkInStationId < 10) || (!indoor && cumulus.AirLinkOutStationId < 10)) { cumulus.LogMessage($"GetAvailableSensors: No WeatherLink AirLink API station ID has been configured, aborting!"); return; } + var sensorsUrl = "https://api.weatherlink.com/v2/sensors?api-key=" + cumulus.AirLinkApiKey; - SortedDictionary parameters = new SortedDictionary - { - { "api-key", apiKey }, - { "t", unixDateTime.ToString() } - }; - - StringBuilder dataStringBuilder = new StringBuilder(); - foreach (KeyValuePair entry in parameters) - { - dataStringBuilder.Append(entry.Key); - dataStringBuilder.Append(entry.Value); - } - string header = dataStringBuilder.ToString(); - - var apiSignature = WlDotCom.CalculateApiSignature(apiSecret, header); - parameters.Add("api-signature", apiSignature); - - StringBuilder sensorsUrl = new StringBuilder(); - sensorsUrl.Append("https://api.weatherlink.com/v2/sensors?"); - foreach (KeyValuePair entry in parameters) - { - sensorsUrl.Append(entry.Key); - sensorsUrl.Append('='); - sensorsUrl.Append(entry.Value); - sensorsUrl.Append('&'); - } - // remove the trailing "&" - sensorsUrl.Remove(sensorsUrl.Length - 1, 1); - - var logUrl = sensorsUrl.ToString().Replace(apiKey, "<>"); - cumulus.LogDebugMessage($"GetAvailableSensors: URL = {logUrl}"); + cumulus.LogDebugMessage($"GetAvailableSensors: URL = {sensorsUrl.ToString().Replace(cumulus.AirLinkApiKey, "API_KEY")}"); try { string responseBody; int responseCode; - // We want to do this synchronously - using (var response = Cumulus.MyHttpClient.GetAsync(sensorsUrl.ToString()).Result) + + var request = new HttpRequestMessage(HttpMethod.Get, sensorsUrl); + request.Headers.Add("X-Api-Secret", cumulus.AirLinkApiSecret); + + // we want to do this synchronously, so .Result + using (var response = Cumulus.MyHttpClient.SendAsync(request).Result) { responseBody = response.Content.ReadAsStringAsync().Result; responseCode = (int)response.StatusCode; diff --git a/CumulusMX/DavisWllStation.cs b/CumulusMX/DavisWllStation.cs index 36e7265a..be8a4668 100644 --- a/CumulusMX/DavisWllStation.cs +++ b/CumulusMX/DavisWllStation.cs @@ -13,6 +13,9 @@ using System.Timers; using Tmds.MDns; using Swan; +using System.Web; +using System.Net.Http; +using ServiceStack.Text; namespace CumulusMX { @@ -1549,43 +1552,12 @@ private void GetWlHistoricData(BackgroundWorker worker) cumulus.LogConsoleMessage($"Downloading Historic Data from WL.com from: {cumulus.LastUpdateTime:s} to: {Utils.FromUnixTime(endTime):s}"); cumulus.LogMessage($"GetWlHistoricData: Downloading Historic Data from WL.com from: {cumulus.LastUpdateTime:s} to: {Utils.FromUnixTime(endTime):s}"); - SortedDictionary parameters = new SortedDictionary - { - { "api-key", cumulus.WllApiKey }, - { "station-id", cumulus.WllStationId.ToString() }, - { "t", unixDateTime.ToString() }, - { "start-timestamp", startTime.ToString() }, - { "end-timestamp", endTime.ToString() } - }; - - StringBuilder dataStringBuilder = new StringBuilder(); - foreach (KeyValuePair entry in parameters) - { - dataStringBuilder.Append(entry.Key); - dataStringBuilder.Append(entry.Value); - } - - string data = dataStringBuilder.ToString(); - - var apiSignature = WlDotCom.CalculateApiSignature(cumulus.WllApiSecret, data); + StringBuilder historicUrl = new StringBuilder("https://api.weatherlink.com/v2/historic/" + cumulus.WllStationId); + historicUrl.Append("?api-key=" + cumulus.WllApiKey); + historicUrl.Append("&start-timestamp=" + startTime.ToString()); + historicUrl.Append("&end-timestamp=" + endTime.ToString()); - parameters.Remove("station-id"); - parameters.Add("api-signature", apiSignature); - - StringBuilder historicUrl = new StringBuilder(); - historicUrl.Append("https://api.weatherlink.com/v2/historic/" + cumulus.WllStationId + "?"); - foreach (KeyValuePair entry in parameters) - { - historicUrl.Append(entry.Key); - historicUrl.Append('='); - historicUrl.Append(entry.Value); - historicUrl.Append('&'); - } - // remove the trailing "&" - historicUrl.Remove(historicUrl.Length - 1, 1); - - var logUrl = historicUrl.ToString().Replace(cumulus.WllApiKey, "<>"); - cumulus.LogDebugMessage($"WeatherLink URL = {logUrl}"); + cumulus.LogDebugMessage($"WeatherLink URL = {historicUrl.ToString().Replace(cumulus.WllApiKey, "API_KEY")}"); lastDataReadTime = cumulus.LastUpdateTime; int luhour = lastDataReadTime.Hour; @@ -1607,8 +1579,11 @@ private void GetWlHistoricData(BackgroundWorker worker) string responseBody; int responseCode; + var request = new HttpRequestMessage(HttpMethod.Get, historicUrl.ToString()); + request.Headers.Add("X-Api-Secret", cumulus.WllApiSecret); + // we want to do this synchronously, so .Result - using (var response = Cumulus.MyHttpClient.GetAsync(historicUrl.ToString()).Result) + using (var response = Cumulus.MyHttpClient.SendAsync(request).Result) { responseBody = response.Content.ReadAsStringAsync().Result; responseCode = (int)response.StatusCode; @@ -2903,52 +2878,24 @@ private void GetWlHistoricHealth() cumulus.LogDebugMessage($"WLL Health: Downloading the historic record from WL.com from: {Utils.FromUnixTime(startTime):s} to: {Utils.FromUnixTime(endTime):s}"); - SortedDictionary parameters = new SortedDictionary - { - { "api-key", cumulus.WllApiKey }, - { "station-id", cumulus.WllStationId.ToString() }, - { "t", unixDateTime.ToString() }, - { "start-timestamp", startTime.ToString() }, - { "end-timestamp", endTime.ToString() } - }; - - StringBuilder dataStringBuilder = new StringBuilder(); - foreach (KeyValuePair entry in parameters) - { - dataStringBuilder.Append(entry.Key); - dataStringBuilder.Append(entry.Value); - } - - string data = dataStringBuilder.ToString(); - - var apiSignature = WlDotCom.CalculateApiSignature(cumulus.WllApiSecret, data); + StringBuilder historicUrl = new StringBuilder("https://api.weatherlink.com/v2/historic/" + cumulus.WllStationId); + historicUrl.Append("?api-key=" + cumulus.WllApiKey); + historicUrl.Append("&start-timestamp=" + startTime.ToString()); + historicUrl.Append("&end-timestamp=" + endTime.ToString()); - parameters.Remove("station-id"); - parameters.Add("api-signature", apiSignature); - - StringBuilder historicUrl = new StringBuilder(); - historicUrl.Append("https://api.weatherlink.com/v2/historic/" + cumulus.WllStationId + "?"); - foreach (KeyValuePair entry in parameters) - { - historicUrl.Append(entry.Key); - historicUrl.Append('='); - historicUrl.Append(entry.Value); - historicUrl.Append('&'); - } - // remove the trailing "&" - historicUrl.Remove(historicUrl.Length - 1, 1); - - var logUrl = historicUrl.ToString().Replace(cumulus.WllApiKey, "<>"); - cumulus.LogDebugMessage($"WLL Health: WeatherLink URL = {logUrl}"); + cumulus.LogDebugMessage($"WLL Health: WeatherLink URL = {historicUrl.ToString().Replace(cumulus.WllApiKey, "API_KEY")}"); try { - // we want to do this synchronously, so .Result WlHistory histObj; string responseBody; int responseCode; - using (var response = Cumulus.MyHttpClient.GetAsync(historicUrl.ToString()).Result) + var request = new HttpRequestMessage(HttpMethod.Get, historicUrl.ToString()); + request.Headers.Add("X-Api-Secret", cumulus.WllApiSecret); + + // we want to do this synchronously, so .Result + using (var response = Cumulus.MyHttpClient.SendAsync(request).Result) { responseBody = response.Content.ReadAsStringAsync().Result; responseCode = (int)response.StatusCode; @@ -3088,45 +3035,20 @@ private void GetAvailableStationIds(bool logToConsole = false) return; } - SortedDictionary parameters = new SortedDictionary - { - { "api-key", cumulus.WllApiKey }, - { "t", unixDateTime.ToString() } - }; + var stationsUrl = "https://api.weatherlink.com/v2/stations?api-key=" + cumulus.WllApiKey; - StringBuilder dataStringBuilder = new StringBuilder(); - foreach (KeyValuePair entry in parameters) - { - dataStringBuilder.Append(entry.Key); - dataStringBuilder.Append(entry.Value); - } - string header = dataStringBuilder.ToString(); - - var apiSignature = WlDotCom.CalculateApiSignature(cumulus.WllApiSecret, header); - parameters.Add("api-signature", apiSignature); - - StringBuilder stationsUrl = new StringBuilder(); - stationsUrl.Append("https://api.weatherlink.com/v2/stations?"); - foreach (KeyValuePair entry in parameters) - { - stationsUrl.Append(entry.Key); - stationsUrl.Append('='); - stationsUrl.Append(entry.Value); - stationsUrl.Append('&'); - } - // remove the trailing "&" - stationsUrl.Remove(stationsUrl.Length - 1, 1); - - var logUrl = stationsUrl.ToString().Replace(cumulus.WllApiKey, "<>"); - cumulus.LogDebugMessage($"WLLStations: URL = {logUrl}"); + cumulus.LogDebugMessage($"WLLStations: URL = {stationsUrl.ToString().Replace(cumulus.WllApiKey, "API_KEY")}"); try { - // We want to do this synchronously string responseBody; int responseCode; - using (var response = Cumulus.MyHttpClient.GetAsync(stationsUrl.ToString()).Result) + var request = new HttpRequestMessage(HttpMethod.Get, stationsUrl.ToString()); + request.Headers.Add("X-Api-Secret", cumulus.WllApiSecret); + + // We want to do this synchronously + using (var response = Cumulus.MyHttpClient.SendAsync(request).Result) { responseBody = response.Content.ReadAsStringAsync().Result; responseCode = (int)response.StatusCode; @@ -3201,50 +3123,24 @@ private void GetAvailableSensors() return; } - SortedDictionary parameters = new SortedDictionary - { - { "api-key", cumulus.WllApiKey }, - { "t", unixDateTime.ToString() } - }; - - StringBuilder dataStringBuilder = new StringBuilder(); - foreach (KeyValuePair entry in parameters) - { - dataStringBuilder.Append(entry.Key); - dataStringBuilder.Append(entry.Value); - } - string header = dataStringBuilder.ToString(); - - var apiSignature = WlDotCom.CalculateApiSignature(cumulus.WllApiSecret, header); - parameters.Add("api-signature", apiSignature); + var stationsUrl = "https://api.weatherlink.com/v2/sensors?api-key=" + cumulus.WllApiKey; - StringBuilder stationsUrl = new StringBuilder(); - stationsUrl.Append("https://api.weatherlink.com/v2/sensors?"); - foreach (KeyValuePair entry in parameters) - { - stationsUrl.Append(entry.Key); - stationsUrl.Append('='); - stationsUrl.Append(entry.Value); - stationsUrl.Append('&'); - } - // remove the trailing "&" - stationsUrl.Remove(stationsUrl.Length - 1, 1); - - var logUrl = stationsUrl.ToString().Replace(cumulus.WllApiKey, "<>"); - cumulus.LogDebugMessage($"GetAvailableSensors: URL = {logUrl}"); + cumulus.LogDebugMessage($"GetAvailableSensors: URL = {stationsUrl.Replace(cumulus.WllApiKey, "API_KEY")}"); WlSensorList sensorsObj = new WlSensorList(); try { - // We want to do this synchronously string responseBody; int responseCode; + var request = new HttpRequestMessage(HttpMethod.Get, stationsUrl); + request.Headers.Add("X-Api-Secret", cumulus.WllApiSecret); - using (var response = Cumulus.MyHttpClient.GetAsync(stationsUrl.ToString()).Result) + // We want to do this synchronously + using (var response = Cumulus.MyHttpClient.SendAsync(request).Result) { responseBody = response.Content.ReadAsStringAsync().Result; - responseCode = (int)response.StatusCode; + responseCode = (int) response.StatusCode; cumulus.LogDebugMessage($"GetAvailableSensors: WeatherLink API Response: {responseCode}: {responseBody}"); } diff --git a/CumulusMX/WeatherLinkDotCom.cs b/CumulusMX/WeatherLinkDotCom.cs index e35f17d5..0dcc3032 100644 --- a/CumulusMX/WeatherLinkDotCom.cs +++ b/CumulusMX/WeatherLinkDotCom.cs @@ -6,23 +6,6 @@ namespace CumulusMX { - internal class WlDotCom - { - public static string CalculateApiSignature(string apiSecret, string data) - { - /* - Calculate the HMAC SHA-256 hash that will be used as the API Signature. - */ - string apiSignatureString; - using (HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(apiSecret))) - { - byte[] apiSignatureBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(data)); - apiSignatureString = BitConverter.ToString(apiSignatureBytes).Replace("-", "").ToLower(); - } - return apiSignatureString; - } - } - public class WlHistory { public int station_id { get; set; } diff --git a/CumulusMX/WeatherStation.cs b/CumulusMX/WeatherStation.cs index 5b61e9a7..1bafccd5 100644 --- a/CumulusMX/WeatherStation.cs +++ b/CumulusMX/WeatherStation.cs @@ -13974,7 +13974,7 @@ public void UpdateAPRS() return; } - cumulus.LogMessage("Updating CWOP"); + cumulus.LogDebugMessage("Updating CWOP"); using (var client = new TcpClient(cumulus.APRS.Server, cumulus.APRS.Port)) using (var ns = client.GetStream()) { diff --git a/Updates.txt b/Updates.txt index 79c5c207..78db8fd8 100644 --- a/Updates.txt +++ b/Updates.txt @@ -17,6 +17,7 @@ Changed - Various third party libraries updated to current versions - MailKit, MQTTnet, MySqlConnector, ServiceStack - PHP upload now sends a text/plain content header +- Davis WLL and Airlink now use the new simplified access method to weatherlink.com V2 API Fixed - PWS passwords are now URL encoded From ef697d1e534ee92d3d2d8522ea57327fc6c28e83 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Sun, 2 Jul 2023 18:22:11 +0100 Subject: [PATCH 15/27] Updating MySQL on DayFile edits was erroring with a blank SQL statement --- CumulusMX/DataEditor.cs | 6 +++--- Updates.txt | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CumulusMX/DataEditor.cs b/CumulusMX/DataEditor.cs index 5d5d63f0..bb054f62 100644 --- a/CumulusMX/DataEditor.cs +++ b/CumulusMX/DataEditor.cs @@ -3376,10 +3376,10 @@ internal string EditDayFile(IHttpContext context) updt.Append($"DomWindDir={station.DayFile[lineNum].DominantWindBearing},"); updt.Append($"HeatDegDays={(station.DayFile[lineNum].HeatingDegreeDays > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].HeatingDegreeDays.ToString("F1", InvC)}'" : "NULL")},"); updt.Append($"CoolDegDays={(station.DayFile[lineNum].CoolingDegreeDays > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].CoolingDegreeDays.ToString("F1", InvC)}'" : "NULL")},"); - updt.Append($"HighSolarRad={(station.DayFile[lineNum].HighSolar > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].HighSolar}'" : "NULL")},"); - updt.Append($"THighSolarRad={(station.DayFile[lineNum].HighSolar > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].HighSolarTime:\\'HH:mm\\}'" : "NULL")},"); + updt.Append($"HighSolarRad={(station.DayFile[lineNum].HighSolar > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].HighSolar.ToString()}'" : "NULL")},"); + updt.Append($"THighSolarRad={(station.DayFile[lineNum].HighSolar > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].HighSolarTime.ToString("HH:mm")}'" : "NULL")},"); updt.Append($"HighUV={(station.DayFile[lineNum].HighUv > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].HighUv.ToString(cumulus.UVFormat, InvC)}'" : "NULL")},"); - updt.Append($"THighUV={(station.DayFile[lineNum].HighUv > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].HighUvTime:\\'HH:mm\\'}'" : "NULL")},"); + updt.Append($"THighUV={(station.DayFile[lineNum].HighUv > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].HighUvTime.ToString("HH:mm")}'" : "NULL")},"); updt.Append($"HWindGBearSym='{station.CompassPoint(station.DayFile[lineNum].HighGustBearing)}',"); updt.Append($"DomWindDirSym='{station.CompassPoint(station.DayFile[lineNum].DominantWindBearing)}',"); updt.Append($"MaxFeelsLike={(station.DayFile[lineNum].HighFeelsLike > Cumulus.DefaultHiVal ? station.DayFile[lineNum].HighFeelsLike.ToString(cumulus.TempFormat, InvC) : "NULL")},"); diff --git a/Updates.txt b/Updates.txt index 78db8fd8..a896320d 100644 --- a/Updates.txt +++ b/Updates.txt @@ -26,12 +26,13 @@ Fixed - Davis VP2 stations creating incorrect values for Wind Run and Chill Hours if some logger data is missing - Instromet station now forces MX to calculate the average wind speed - FTP logging errors when FTP logging is already enabled at start-up +- Updating MySQL on DayFile edits was erroring with a blank SQL statement 3.25.2 - b3245 —————————————— Fixed -- Davis WLL not doing historic catch-up or downloading stats from weatherlink.com +- Davis WLL/AirLink not doing historic catch-up or downloading stats from weatherlink.com From 1ca5f363c94640007717f4e49d5c86ab5d236685 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Mon, 3 Jul 2023 10:41:35 +0100 Subject: [PATCH 16/27] Update Nuget packages Fix the Dayfile MySQL format fix! --- CumulusMX/CumulusMX.csproj | 6 +++--- CumulusMX/DataEditor.cs | 38 +++++++++++++++++++------------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/CumulusMX/CumulusMX.csproj b/CumulusMX/CumulusMX.csproj index 8bd3b8dc..da44e3d0 100644 --- a/CumulusMX/CumulusMX.csproj +++ b/CumulusMX/CumulusMX.csproj @@ -239,10 +239,10 @@ 2.1.0 - 4.0.0 + 4.1.0 - 4.2.0.706 + 4.2.1.781 2.2.6 @@ -251,7 +251,7 @@ 2.2.5 - 6.8.0 + 6.9.0 2020.0.2 diff --git a/CumulusMX/DataEditor.cs b/CumulusMX/DataEditor.cs index bb054f62..c63a59f4 100644 --- a/CumulusMX/DataEditor.cs +++ b/CumulusMX/DataEditor.cs @@ -3354,43 +3354,43 @@ internal string EditDayFile(IHttpContext context) updt.Append($"HighAvgWSpeed={station.DayFile[lineNum].HighAvgWind.ToString(cumulus.WindAvgFormat, InvC)},"); updt.Append($"THAvgWSpeed={station.DayFile[lineNum].HighAvgWindTime:\\'HH:mm\\'},"); updt.Append($"LowHum={(station.DayFile[lineNum].LowHumidity < Cumulus.DefaultLoVal ? station.DayFile[lineNum].LowHumidity.ToString() : "NULL")},"); - updt.Append($"TLowHum={(station.DayFile[lineNum].LowHumidity < Cumulus.DefaultLoVal ? $"'{station.DayFile[lineNum].LowHumidityTime.ToString("HH:mm")}'" : "NULL")},"); + updt.Append($"TLowHum={(station.DayFile[lineNum].LowHumidity < Cumulus.DefaultLoVal ? station.DayFile[lineNum].LowHumidityTime.ToString("\\'HH:mm\\'") : "NULL")},"); updt.Append($"HighHum={(station.DayFile[lineNum].HighHumidity > Cumulus.DefaultHiVal ? station.DayFile[lineNum].HighHumidity.ToString() : "NULL")},"); - updt.Append($"THighHum={(station.DayFile[lineNum].HighHumidity > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].HighHumidityTime.ToString("HH:mm")}'" : "NULL")},"); + updt.Append($"THighHum={(station.DayFile[lineNum].HighHumidity > Cumulus.DefaultHiVal ? station.DayFile[lineNum].HighHumidityTime.ToString("\\'HH:mm\\'") : "NULL")},"); updt.Append($"TotalEvap={station.DayFile[lineNum].ET.ToString(cumulus.ETFormat, InvC)},"); updt.Append($"HoursSun={station.DayFile[lineNum].SunShineHours.ToString(cumulus.SunFormat, InvC)},"); updt.Append($"HighHeatInd={(station.DayFile[lineNum].HighHeatIndex > Cumulus.DefaultHiVal ? station.DayFile[lineNum].HighHeatIndex.ToString(cumulus.TempFormat, InvC) : "NULL")},"); - updt.Append($"THighHeatInd={(station.DayFile[lineNum].HighHeatIndex > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].HighHeatIndexTime.ToString("HH:mm")}'" : "NULL")},"); + updt.Append($"THighHeatInd={(station.DayFile[lineNum].HighHeatIndex > Cumulus.DefaultHiVal ? station.DayFile[lineNum].HighHeatIndexTime.ToString("\\'HH:mm\\'") : "NULL")},"); updt.Append($"HighAppTemp={(station.DayFile[lineNum].HighAppTemp > Cumulus.DefaultHiVal ? station.DayFile[lineNum].HighAppTemp.ToString(cumulus.TempFormat, InvC) : "NULL")},"); - updt.Append($"THighAppTemp={(station.DayFile[lineNum].HighAppTemp > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].HighAppTempTime.ToString("HH:mm")}'" : "NULL")},"); - updt.Append($"LowAppTemp={(station.DayFile[lineNum].LowAppTemp < Cumulus.DefaultLoVal ? station.DayFile[lineNum].LowAppTemp.ToString(cumulus.TempFormat, InvC) : "NULL")},"); - updt.Append($"TLowAppTemp={(station.DayFile[lineNum].LowAppTemp < Cumulus.DefaultLoVal ? $"'{station.DayFile[lineNum].LowAppTempTime.ToString("HH:mm")}'" : "NULL")},"); + updt.Append($"THighAppTemp={(station.DayFile[lineNum].HighAppTemp > Cumulus.DefaultHiVal ? station.DayFile[lineNum].HighAppTempTime.ToString("\\'HH:mm\\'") : "NULL")},"); + updt.Append($"LowAppTemp={(station.DayFile[lineNum].LowAppTemp < Cumulus.DefaultLoVal ? station.DayFile[lineNum].LowAppTemp.ToString(cumulus.TempFormat, InvC) : "NULL")},"); + updt.Append($"TLowAppTemp={(station.DayFile[lineNum].LowAppTemp < Cumulus.DefaultLoVal ? station.DayFile[lineNum].LowAppTempTime.ToString("\\'HH:mm\\'") : "NULL")},"); updt.Append($"HighHourRain={station.DayFile[lineNum].HighHourlyRain.ToString(cumulus.RainFormat, InvC)},"); updt.Append($"THighHourRain={station.DayFile[lineNum].HighHourlyRainTime:\\'HH:mm\\'},"); updt.Append($"LowWindChill={(station.DayFile[lineNum].LowWindChill < Cumulus.DefaultLoVal ? station.DayFile[lineNum].LowWindChill.ToString(cumulus.TempFormat, InvC) : "NULL")},"); - updt.Append($"TLowWindChill={(station.DayFile[lineNum].LowWindChill < Cumulus.DefaultLoVal ? $"'{station.DayFile[lineNum].LowWindChillTime.ToString("HH:mm")}'" : "NULL")},"); + updt.Append($"TLowWindChill={(station.DayFile[lineNum].LowWindChill < Cumulus.DefaultLoVal ? station.DayFile[lineNum].LowWindChillTime.ToString("\\'HH:mm\\'") : "NULL")},"); updt.Append($"HighDewPoint={(station.DayFile[lineNum].HighDewPoint > Cumulus.DefaultHiVal ? station.DayFile[lineNum].HighDewPoint.ToString(cumulus.TempFormat, InvC) : "NULL")},"); - updt.Append($"THighDewPoint={(station.DayFile[lineNum].HighDewPoint > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].HighDewPointTime.ToString("HH:mm")}'" : "NULL")},"); + updt.Append($"THighDewPoint={(station.DayFile[lineNum].HighDewPoint > Cumulus.DefaultHiVal ? station.DayFile[lineNum].HighDewPointTime.ToString("\\'HH:mm\\'") : "NULL")},"); updt.Append($"LowDewPoint={(station.DayFile[lineNum].LowDewPoint < Cumulus.DefaultLoVal ? station.DayFile[lineNum].LowDewPoint.ToString(cumulus.TempFormat, InvC) : "NULL")},"); - updt.Append($"TLowDewPoint={(station.DayFile[lineNum].LowDewPoint < Cumulus.DefaultLoVal ? $"'{station.DayFile[lineNum].LowDewPointTime.ToString("HH:mm")}'" : "NULL")},"); + updt.Append($"TLowDewPoint={(station.DayFile[lineNum].LowDewPoint < Cumulus.DefaultLoVal ? station.DayFile[lineNum].LowDewPointTime.ToString("\\'HH:mm\\'") : "NULL")},"); updt.Append($"DomWindDir={station.DayFile[lineNum].DominantWindBearing},"); - updt.Append($"HeatDegDays={(station.DayFile[lineNum].HeatingDegreeDays > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].HeatingDegreeDays.ToString("F1", InvC)}'" : "NULL")},"); - updt.Append($"CoolDegDays={(station.DayFile[lineNum].CoolingDegreeDays > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].CoolingDegreeDays.ToString("F1", InvC)}'" : "NULL")},"); - updt.Append($"HighSolarRad={(station.DayFile[lineNum].HighSolar > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].HighSolar.ToString()}'" : "NULL")},"); - updt.Append($"THighSolarRad={(station.DayFile[lineNum].HighSolar > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].HighSolarTime.ToString("HH:mm")}'" : "NULL")},"); - updt.Append($"HighUV={(station.DayFile[lineNum].HighUv > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].HighUv.ToString(cumulus.UVFormat, InvC)}'" : "NULL")},"); - updt.Append($"THighUV={(station.DayFile[lineNum].HighUv > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].HighUvTime.ToString("HH:mm")}'" : "NULL")},"); + updt.Append($"HeatDegDays={(station.DayFile[lineNum].HeatingDegreeDays > Cumulus.DefaultHiVal ? station.DayFile[lineNum].HeatingDegreeDays.ToString("F1", InvC) : "NULL")},"); + updt.Append($"CoolDegDays={(station.DayFile[lineNum].CoolingDegreeDays > Cumulus.DefaultHiVal ? station.DayFile[lineNum].CoolingDegreeDays.ToString("F1", InvC) : "NULL")},"); + updt.Append($"HighSolarRad={(station.DayFile[lineNum].HighSolar > Cumulus.DefaultHiVal ? station.DayFile[lineNum].HighSolar.ToString() : "NULL")},"); + updt.Append($"THighSolarRad={(station.DayFile[lineNum].HighSolar > Cumulus.DefaultHiVal ? station.DayFile[lineNum].HighSolarTime.ToString("\\'HH:mm\\'") : "NULL")},"); + updt.Append($"HighUV={(station.DayFile[lineNum].HighUv > Cumulus.DefaultHiVal ? station.DayFile[lineNum].HighUv.ToString(cumulus.UVFormat, InvC) : "NULL")},"); + updt.Append($"THighUV={(station.DayFile[lineNum].HighUv > Cumulus.DefaultHiVal ? station.DayFile[lineNum].HighUvTime.ToString("\\'HH:mm\\'") : "NULL")},"); updt.Append($"HWindGBearSym='{station.CompassPoint(station.DayFile[lineNum].HighGustBearing)}',"); updt.Append($"DomWindDirSym='{station.CompassPoint(station.DayFile[lineNum].DominantWindBearing)}',"); updt.Append($"MaxFeelsLike={(station.DayFile[lineNum].HighFeelsLike > Cumulus.DefaultHiVal ? station.DayFile[lineNum].HighFeelsLike.ToString(cumulus.TempFormat, InvC) : "NULL")},"); - updt.Append($"TMaxFeelsLike={(station.DayFile[lineNum].HighFeelsLike > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].HighFeelsLikeTime.ToString("HH:mm")}'" : "NULL")},"); + updt.Append($"TMaxFeelsLike={(station.DayFile[lineNum].HighFeelsLike > Cumulus.DefaultHiVal ? station.DayFile[lineNum].HighFeelsLikeTime.ToString("\\'HH:mm\\'") : "NULL")},"); updt.Append($"MinFeelsLike={(station.DayFile[lineNum].LowFeelsLike < Cumulus.DefaultLoVal ? station.DayFile[lineNum].LowFeelsLike.ToString(cumulus.TempFormat, InvC) : "NULL")},"); - updt.Append($"TMinFeelsLike={(station.DayFile[lineNum].LowFeelsLike < Cumulus.DefaultLoVal ? $"'{station.DayFile[lineNum].LowFeelsLikeTime.ToString("HH:mm")}'" : "NULL")},"); + updt.Append($"TMinFeelsLike={(station.DayFile[lineNum].LowFeelsLike < Cumulus.DefaultLoVal ? station.DayFile[lineNum].LowFeelsLikeTime.ToString("\\'HH:mm\\'") : "NULL")},"); updt.Append($"MaxHumidex={(station.DayFile[lineNum].HighHumidex > Cumulus.DefaultHiVal ? station.DayFile[lineNum].HighHumidex.ToString(cumulus.TempFormat, InvC) : "NULL")},"); - updt.Append($"TMaxHumidex={(station.DayFile[lineNum].HighHumidex > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].HighHumidexTime.ToString("HH:mm")}'" : "NULL")},"); + updt.Append($"TMaxHumidex={(station.DayFile[lineNum].HighHumidex > Cumulus.DefaultHiVal ? station.DayFile[lineNum].HighHumidexTime.ToString("\\'HH:mm\\'") : "NULL")},"); updt.Append($"ChillHours={(station.DayFile[lineNum].ChillHours > Cumulus.DefaultHiVal ? station.DayFile[lineNum].ChillHours.ToString("F1", InvC) : "NULL")},"); updt.Append($"HighRain24h={(station.DayFile[lineNum].HighRain24h > Cumulus.DefaultHiVal ? station.DayFile[lineNum].HighRain24h.ToString(cumulus.RainFormat, InvC) : "NULL")},"); - updt.Append($"THighRain24h={(station.DayFile[lineNum].HighRain24h > Cumulus.DefaultHiVal ? $"'{station.DayFile[lineNum].HighRain24hTime.ToString("HH:mm")}'" : "NULL")} "); + updt.Append($"THighRain24h={(station.DayFile[lineNum].HighRain24h > Cumulus.DefaultHiVal ? station.DayFile[lineNum].HighRain24hTime.ToString("\\'HH:mm\\'") : "NULL")} "); updt.Append($"WHERE LogDate='{station.DayFile[lineNum].Date:yyyy-MM-dd}';"); updateStr = updt.ToString(); From 212a30657a90c7b46c97891fff24a5a120e762a0 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Mon, 3 Jul 2023 10:46:47 +0100 Subject: [PATCH 17/27] Change Alarm emails to use BCC for the destination addresses --- CumulusMX/EmailSender.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CumulusMX/EmailSender.cs b/CumulusMX/EmailSender.cs index bf57e300..f1f0aa87 100644 --- a/CumulusMX/EmailSender.cs +++ b/CumulusMX/EmailSender.cs @@ -42,7 +42,7 @@ public async Task SendEmail(string[] to, string from, string subject, stri m.From.Add(new MailboxAddress("", from)); foreach (var addr in to) { - m.To.Add(new MailboxAddress("", addr)); + m.Bcc.Add(new MailboxAddress("", addr)); } m.Subject = sendSubject; From 5ddd3b761d484e6e99c149f181fcb704dea5f449 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Mon, 3 Jul 2023 14:51:09 +0100 Subject: [PATCH 18/27] Alarm email BCC now user selectable --- CumulusMX/Alarm.cs | 2 +- CumulusMX/AlarmSettings.cs | 5 ++++- CumulusMX/Cumulus.cs | 4 +++- CumulusMX/EmailSender.cs | 7 +++++-- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CumulusMX/Alarm.cs b/CumulusMX/Alarm.cs index 4a4ac537..7fbf6d09 100644 --- a/CumulusMX/Alarm.cs +++ b/CumulusMX/Alarm.cs @@ -105,7 +105,7 @@ private void doTriggered(bool value) cumulus.LogMessage($"Alarm ({Name}): Sending email - attempt {i + 1}"); - if (await cumulus.emailer.SendEmail(cumulus.AlarmDestEmail, cumulus.AlarmFromEmail, cumulus.Trans.AlarmEmailSubject, msg, cumulus.AlarmEmailHtml)) + if (await cumulus.emailer.SendEmail(cumulus.AlarmDestEmail, cumulus.AlarmFromEmail, cumulus.Trans.AlarmEmailSubject, msg, cumulus.AlarmEmailHtml, cumulus.AlarmEmailUseBcc)) { break; } diff --git a/CumulusMX/AlarmSettings.cs b/CumulusMX/AlarmSettings.cs index 07df7d6d..cf7c1054 100644 --- a/CumulusMX/AlarmSettings.cs +++ b/CumulusMX/AlarmSettings.cs @@ -268,7 +268,8 @@ public string GetAlarmSettings() { fromEmail = cumulus.AlarmFromEmail, destEmail = cumulus.AlarmDestEmail.Join(";"), - useHtml = cumulus.AlarmEmailHtml + useHtml = cumulus.AlarmEmailHtml, + useBcc = cumulus.AlarmEmailUseBcc }; var retObject = new JsonAlarmSettings() @@ -559,6 +560,7 @@ public string UpdateAlarmSettings(IHttpContext context) } cumulus.AlarmDestEmail = emails; cumulus.AlarmEmailHtml = result.email.useHtml; + cumulus.AlarmEmailUseBcc = result.email.useBcc; // Save the settings cumulus.WriteIniFile(); @@ -678,6 +680,7 @@ public class JsonAlarmEmail public string fromEmail { get; set; } public string destEmail { get; set; } public bool useHtml { get; set; } + public bool useBcc { get; set; } } public class JsonAlarmUnits diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index b08af009..0d385ad7 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -445,6 +445,7 @@ public struct TExtraFiles public string AlarmFromEmail; public string[] AlarmDestEmail; public bool AlarmEmailHtml; + public bool AlarmEmailUseBcc; public bool RealtimeIntervalEnabled; // The timer is to be started private int realtimeFTPRetries; // Count of failed realtime FTP attempts @@ -5373,6 +5374,7 @@ private void ReadIniFile() AlarmFromEmail = ini.GetValue("Alarms", "FromEmail", ""); AlarmDestEmail = ini.GetValue("Alarms", "DestEmail", "").Split(';'); AlarmEmailHtml = ini.GetValue("Alarms", "UseHTML", false); + AlarmEmailUseBcc = ini.GetValue("Alarms", "UseBCC", false); Calib.Press.Offset = ini.GetValue("Offsets", "PressOffset", 0.0); Calib.Temp.Offset = ini.GetValue("Offsets", "TempOffset", 0.0); @@ -6533,7 +6535,7 @@ internal void WriteIniFile() ini.SetValue("Alarms", "FromEmail", AlarmFromEmail); ini.SetValue("Alarms", "DestEmail", AlarmDestEmail.Join(";")); ini.SetValue("Alarms", "UseHTML", AlarmEmailHtml); - + ini.SetValue("Alarms", "UseBCC", AlarmEmailUseBcc); ini.SetValue("Offsets", "PressOffset", Calib.Press.Offset); ini.SetValue("Offsets", "TempOffset", Calib.Temp.Offset); diff --git a/CumulusMX/EmailSender.cs b/CumulusMX/EmailSender.cs index f1f0aa87..9159c9f1 100644 --- a/CumulusMX/EmailSender.cs +++ b/CumulusMX/EmailSender.cs @@ -24,7 +24,7 @@ public EmailSender(Cumulus cumulus) } - public async Task SendEmail(string[] to, string from, string subject, string message, bool isHTML) + public async Task SendEmail(string[] to, string from, string subject, string message, bool isHTML, bool useBcc) { bool retVal = false; try @@ -42,7 +42,10 @@ public async Task SendEmail(string[] to, string from, string subject, stri m.From.Add(new MailboxAddress("", from)); foreach (var addr in to) { - m.Bcc.Add(new MailboxAddress("", addr)); + if (useBcc) + m.Bcc.Add(new MailboxAddress("", addr)); + else + m.To.Add(new MailboxAddress("", addr)); } m.Subject = sendSubject; From 6929c33ba1ab2772110261c25b7296f8b8b09d98 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Tue, 18 Jul 2023 17:44:41 +0100 Subject: [PATCH 19/27] Persist recent wind speeds data across reboots --- CumulusMX/Alarm.cs | 4 +- CumulusMX/Cumulus.cs | 1 + CumulusMX/DavisWllStation.cs | 3 +- CumulusMX/WeatherStation.cs | 127 ++++++++++++++++++++++++++++++----- 4 files changed, 116 insertions(+), 19 deletions(-) diff --git a/CumulusMX/Alarm.cs b/CumulusMX/Alarm.cs index 7fbf6d09..84a4d9c2 100644 --- a/CumulusMX/Alarm.cs +++ b/CumulusMX/Alarm.cs @@ -262,7 +262,7 @@ private void doUpTriggered(bool value) cumulus.LogMessage($"Alarm ({Name}): Sending email - attempt {i + 1}"); - if (await cumulus.emailer.SendEmail(cumulus.AlarmDestEmail, cumulus.AlarmFromEmail, cumulus.Trans.AlarmEmailSubject, msg, cumulus.AlarmEmailHtml)) + if (await cumulus.emailer.SendEmail(cumulus.AlarmDestEmail, cumulus.AlarmFromEmail, cumulus.Trans.AlarmEmailSubject, msg, cumulus.AlarmEmailHtml, cumulus.AlarmEmailUseBcc)) { break; } @@ -336,7 +336,7 @@ private void doDownTriggered(bool value) cumulus.LogMessage($"Alarm ({Name}): Sending email - attempt {i + 1}"); - if (await cumulus.emailer.SendEmail(cumulus.AlarmDestEmail, cumulus.AlarmFromEmail, cumulus.Trans.AlarmEmailSubject, msg, cumulus.AlarmEmailHtml)) + if (await cumulus.emailer.SendEmail(cumulus.AlarmDestEmail, cumulus.AlarmFromEmail, cumulus.Trans.AlarmEmailSubject, msg, cumulus.AlarmEmailHtml, cumulus.AlarmEmailUseBcc)) { break; } diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index 0d385ad7..66dcbd3f 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -9019,6 +9019,7 @@ public void Stop() { LogMessage("No data read this session, today.ini not written"); } + station.SaveWindData(); } catch { } } diff --git a/CumulusMX/DavisWllStation.cs b/CumulusMX/DavisWllStation.cs index be8a4668..d9118e4b 100644 --- a/CumulusMX/DavisWllStation.cs +++ b/CumulusMX/DavisWllStation.cs @@ -829,11 +829,10 @@ private void DecodeCurrent(string currentJson) int wdir = data1.wind_dir_last ?? 0; double wind = ConvertWindMPHToUser(data1.wind_speed_last ?? 0); - var savCalc = cumulus.StationOptions.CalcuateAverageWindSpeed; cumulus.StationOptions.CalcuateAverageWindSpeed = false; CalcRecentMaxGust = false; DoWind(wind, wdir, currentAvgWindSpd, dateTime); - cumulus.StationOptions.CalcuateAverageWindSpeed = savCalc; + cumulus.StationOptions.CalcuateAverageWindSpeed = true; CalcRecentMaxGust = true; } diff --git a/CumulusMX/WeatherStation.cs b/CumulusMX/WeatherStation.cs index 1bafccd5..1ab2571a 100644 --- a/CumulusMX/WeatherStation.cs +++ b/CumulusMX/WeatherStation.cs @@ -417,6 +417,8 @@ public WeatherStation(Cumulus cumulus) RecentDataDb = new SQLiteConnection(new SQLiteConnectionString(cumulus.dbfile, flags, false, null, null, null, null, "yyyy-MM-dd HH:mm:ss")); RecentDataDb.CreateTable(); RecentDataDb.CreateTable(); + RecentDataDb.CreateTable(); + RecentDataDb.Execute("create table if not exists WindRecentPointer (pntr INTEGER)"); // switch off full synchronisation - the data base isn't that critical and we get a performance boost RecentDataDb.Execute("PRAGMA synchronous = NORMAL"); @@ -1546,7 +1548,11 @@ internal async Task sendWebSocketData(bool wait = false) cumulus.LogMessage("sendWebSocketData: Error - " + ex.Message); } - webSocketSemaphore.Release(); + try + { + webSocketSemaphore.Release(); + } + catch { } } private string getTimeString(DateTime time, string format = "HH:mm") @@ -5489,8 +5495,11 @@ public void DoWind(double gustpar, int bearingpar, double speedpar, DateTime tim } } } - // average the values - WindAverage = totalwind / numvalues; + // average the values, if we have enough samples + if (numvalues > 3) + WindAverage = totalwind / numvalues; + else + WindAverage = totalwind / 3; //cumulus.LogDebugMessage("next=" + nextwind + " wind=" + uncalibratedgust + " tot=" + totalwind + " numv=" + numvalues + " avg=" + WindAverage); } else @@ -5612,7 +5621,7 @@ public void DoWind(double gustpar, int bearingpar, double speedpar, DateTime tim public void InitialiseWind() { // first the average - var fromTime = DateTime.Now - cumulus.AvgSpeedTime; + var fromTime = cumulus.LastUpdateTime - cumulus.AvgSpeedTime; var numvalues = 0; var totalwind = 0.0; @@ -5624,23 +5633,22 @@ public void InitialiseWind() totalwind += WindRecent[i].Speed; } } - // average the values - if (numvalues > 0) + // average the values, if we have enough samples + if (numvalues > 3) WindAverage = totalwind / numvalues; + else + WindAverage = totalwind / 3; // now the gust fromTime = DateTime.Now - cumulus.PeakGustTime; - numvalues = 0; - var peakGust = 0.0; for (int i = 0; i < MaxWindRecent; i++) { if (WindRecent[i].Timestamp >= fromTime) { - numvalues++; - if (WindRecent[i].Gust > peakGust) + if (WindRecent[i].Gust > RecentMaxGust) { - peakGust = WindRecent[i].Gust; + RecentMaxGust = WindRecent[i].Gust; } } } @@ -8010,6 +8018,7 @@ public void LoadLastHoursFromDataLogs(DateTime ts) cumulus.LogMessage("Loading last N hour data from data logs: " + ts); LoadRecentFromDataLogs(ts); LoadRecentAqFromDataLogs(ts); + LoadWindData(); LoadLast3HourData(ts); LoadRecentWindRose(); InitialiseWind(); @@ -8314,14 +8323,28 @@ private void LoadLast3HourData(DateTime ts) var result = RecentDataDb.Query("select * from RecentData where Timestamp >= ? and Timestamp <= ? order by Timestamp", datefrom, dateto); + // get the min and max timestamps from the recent wind array + var minWindTs = DateTime.MaxValue; + var maxWindTs = DateTime.MinValue; + foreach (var rec in WindRecent) + { + if (rec.Timestamp < minWindTs) + minWindTs = rec.Timestamp; + if (rec.Timestamp > maxWindTs) + maxWindTs = rec.Timestamp; + } + foreach (var rec in result) { try { - WindRecent[nextwind].Gust = rec.WindGust; - WindRecent[nextwind].Speed = rec.WindSpeed; - WindRecent[nextwind].Timestamp = rec.Timestamp; - nextwind = (nextwind + 1) % MaxWindRecent; + if (rec.Timestamp < minWindTs || rec.Timestamp > maxWindTs) + { + WindRecent[nextwind].Gust = rec.WindGust; + WindRecent[nextwind].Speed = rec.WindSpeed; + WindRecent[nextwind].Timestamp = rec.Timestamp; + nextwind = (nextwind + 1) % MaxWindRecent; + } WindVec[nextwindvec].X = rec.WindGust * Math.Sin(DegToRad(rec.WindDir)); WindVec[nextwindvec].Y = rec.WindGust * Math.Cos(DegToRad(rec.WindDir)); @@ -8337,6 +8360,70 @@ private void LoadLast3HourData(DateTime ts) cumulus.LogMessage($"LoadLast3Hour: Loaded {result.Count} entries to last 3 hour data list"); } + private void LoadWindData() + { + cumulus.LogMessage($"LoadWindData: Attempting to reload the wind speeds array"); + var result = RecentDataDb.Query("select * from CWindRecent"); + + try + { + for (var i = 0; i < result.Count; i++) + { + WindRecent[i].Gust = result[i].Gust; + WindRecent[i].Speed = result[i].Speed; + WindRecent[i].Timestamp = result[i].Timestamp; + } + } + catch (Exception e) + { + cumulus.LogMessage($"LoadWindData: Error loading data from database : {e.Message}"); + } + + try + { + nextwind = RecentDataDb.ExecuteScalar("select * from WindRecentPointer limit 1"); + } + catch (Exception e) + { + cumulus.LogMessage($"LoadWindData: Error loading pointer from database : {e.Message}"); + } + + cumulus.LogMessage($"LoadWindData: Loaded {result.Count} entries to WindRecent data list"); + } + + public void SaveWindData() + { + cumulus.LogMessage($"SaveWindData: Attempting to save the wind speeds array"); + + RecentDataDb.BeginTransaction(); + + try + { + // first empty the tables + RecentDataDb.DeleteAll(); + RecentDataDb.Execute("delete from WindRecentPointer"); + + // save the type array + for (int i = 0; i < WindRecent.Length; i++) + { + if (WindRecent[i].Timestamp > DateTime.MinValue) + RecentDataDb.Execute("insert or replace into CWindRecent (Timestamp,Gust,Speed) values (?,?,?)", WindRecent[i].Timestamp, WindRecent[i].Gust, WindRecent[i].Speed); + } + + // and save the pointer + RecentDataDb.Execute("insert into WindRecentPointer (pntr) values (?)", nextwind); + + RecentDataDb.Commit(); + + cumulus.LogMessage($"SaveWindData: Saved the wind speeds array"); + } + catch (Exception ex) + { + cumulus.LogMessage($"SaveWindData: Error saving RecentWind to the database : {ex.Message}"); + RecentDataDb.Rollback(); + } + } + private static DateTime GetDateTime(DateTime date, string time) { var tim = time.Split(CultureInfo.CurrentCulture.DateTimeFormat.TimeSeparator.ToCharArray()[0]); @@ -14218,6 +14305,7 @@ public void Dispose() // public CumulusData(string connection) : base(connection) { } //} + /* public class Last3HourData { public DateTime timestamp; @@ -14231,6 +14319,15 @@ public Last3HourData(DateTime ts, double press, double temp) temperature = temp; } } + */ + + public class CWindRecent + { + [PrimaryKey] + public DateTime Timestamp { get; set; } + public double Gust { get; set; } // calibrated "gust" as read from station + public double Speed { get; set; } // calibrated "speed" as read from station + } public class LastHourData { From 1f7fdc5fde41d53afd4abd02c6bc65187de6719d Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Sat, 22 Jul 2023 17:35:54 +0100 Subject: [PATCH 20/27] Adds all-time record set alarm --- CumulusMX/Alarm.cs | 21 ++++++- CumulusMX/AlarmSettings.cs | 26 +++++++++ CumulusMX/Cumulus.cs | 72 +++++++++++++++--------- CumulusMX/CumulusMX.csproj | 4 +- CumulusMX/DavisStation.cs | 2 +- CumulusMX/DavisWllStation.cs | 4 +- CumulusMX/FOStation.cs | 8 +-- CumulusMX/GW1000Station.cs | 2 +- CumulusMX/LangSettings.cs | 5 +- CumulusMX/WeatherStation.cs | 105 ++++++++++++----------------------- Updates.txt | 2 + 11 files changed, 142 insertions(+), 109 deletions(-) diff --git a/CumulusMX/Alarm.cs b/CumulusMX/Alarm.cs index 84a4d9c2..f5638cde 100644 --- a/CumulusMX/Alarm.cs +++ b/CumulusMX/Alarm.cs @@ -49,7 +49,7 @@ public bool Triggered public double LatchHours { get; set; } public string EmailMsg { get; set; } public string Units { get; set; } - public string LastError { get; set; } + public string LastMessage { get; set; } public int TriggerThreshold { get; set; } AlarmTypes type; @@ -72,6 +72,12 @@ public void CheckAlarm(double value) } } + public void ClearAlarm() + { + if (Latch && triggered && DateTime.Now > triggeredTime.AddHours(LatchHours)) + doTriggered(false); + } + private void doTriggered(bool value) { if (value) @@ -91,9 +97,9 @@ private void doTriggered(bool value) { // Construct the message - preamble, plus values var msg = cumulus.Trans.AlarmEmailPreamble + "\r\n" + string.Format(EmailMsg, Value, Units); - if (!string.IsNullOrEmpty(LastError)) + if (!string.IsNullOrEmpty(LastMessage)) { - msg += "\r\nLast error: " + LastError; + msg += "\r\nLast message: " + LastMessage; } _ = Task.Run(async () => { @@ -239,6 +245,15 @@ public bool DownTriggered } } + public void ClearAlarm() + { + if (Latch && upTriggered && DateTime.Now > UpTriggeredTime.AddHours(LatchHours)) + doUpTriggered(false); + + if (Latch && downTriggered && DateTime.Now > DownTriggeredTime.AddHours(LatchHours)) + doDownTriggered(false); + } + private void doUpTriggered(bool value) { if (value) diff --git a/CumulusMX/AlarmSettings.cs b/CumulusMX/AlarmSettings.cs index cf7c1054..76426321 100644 --- a/CumulusMX/AlarmSettings.cs +++ b/CumulusMX/AlarmSettings.cs @@ -185,6 +185,19 @@ public string GetAlarmSettings() Action = cumulus.SensorAlarm.Action, ActionParams = cumulus.SensorAlarm.ActionParams }, + newRecord = new JsonAlarmValues() + { + Enabled = cumulus.NewRecordAlarm.Enabled, + SoundEnabled = cumulus.NewRecordAlarm.Sound, + Sound = cumulus.NewRecordAlarm.SoundFile, + Notify = cumulus.NewRecordAlarm.Notify, + Email = cumulus.NewRecordAlarm.Email, + Latches = cumulus.NewRecordAlarm.Latch, + LatchHrs = cumulus.NewRecordAlarm.LatchHours, + Threshold = cumulus.NewRecordAlarm.TriggerThreshold, + Action = cumulus.NewRecordAlarm.Action, + ActionParams = cumulus.NewRecordAlarm.ActionParams + }, dataStopped = new JsonAlarmValues() { Enabled = cumulus.DataStoppedAlarm.Enabled, @@ -449,6 +462,18 @@ public string UpdateAlarmSettings(IHttpContext context) cumulus.HighWindAlarm.Action = settings.windAbove.Action.Trim(); cumulus.HighWindAlarm.ActionParams = settings.windAbove.ActionParams.Trim(); + cumulus.NewRecordAlarm.Enabled = settings.newRecord.Enabled; + cumulus.NewRecordAlarm.Sound = settings.newRecord.SoundEnabled; + cumulus.NewRecordAlarm.SoundFile = settings.newRecord.Sound.Trim(); + cumulus.NewRecordAlarm.Notify = settings.newRecord.Notify; + cumulus.NewRecordAlarm.Email = settings.newRecord.Email; + cumulus.NewRecordAlarm.Latch = settings.newRecord.Latches; + cumulus.NewRecordAlarm.LatchHours = settings.newRecord.LatchHrs; + cumulus.NewRecordAlarm.TriggerThreshold = settings.newRecord.Threshold; + emailRequired = emailRequired || (cumulus.NewRecordAlarm.Email && cumulus.NewRecordAlarm.Enabled); + cumulus.NewRecordAlarm.Action = settings.newRecord.Action.Trim(); + cumulus.NewRecordAlarm.ActionParams = settings.newRecord.ActionParams.Trim(); + cumulus.SensorAlarm.Enabled = settings.contactLost.Enabled; cumulus.SensorAlarm.Sound = settings.contactLost.SoundEnabled; cumulus.SensorAlarm.SoundFile = settings.contactLost.Sound.Trim(); @@ -650,6 +675,7 @@ public class JsonAlarmSettingsData public JsonAlarmValues rainRateAbove { get; set; } public JsonAlarmValues gustAbove { get; set; } public JsonAlarmValues windAbove { get; set; } + public JsonAlarmValues newRecord { get; set; } public JsonAlarmValues contactLost { get; set; } public JsonAlarmValues dataStopped { get; set; } public JsonAlarmValues batteryLow { get; set; } diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index 66dcbd3f..3fe634ad 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -532,6 +532,7 @@ public struct MqttSettings public Alarm HttpUploadAlarm = new Alarm("HTTP Uploads", AlarmTypes.Trigger); public Alarm MySqlUploadAlarm = new Alarm("MySQL Uploads", AlarmTypes.Trigger); public Alarm IsRainingAlarm = new Alarm("IsRaining", AlarmTypes.Trigger); + public Alarm NewRecordAlarm = new Alarm("New Record", AlarmTypes.Trigger); private const double DEFAULTFCLOWPRESS = 950.0; @@ -1384,6 +1385,7 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) HttpUploadAlarm.cumulus = this; MySqlUploadAlarm.cumulus = this; IsRainingAlarm.cumulus = this; + NewRecordAlarm.cumulus = this; GetLatestVersion(); @@ -2245,7 +2247,7 @@ internal async void UpdateWunderground(DateTime timestamp) if (!Wund.RapidFireEnabled || Wund.ErrorFlagCount >= 12) { LogMessage("Wunderground: Response = " + response.StatusCode + ": " + responseBodyAsText); - HttpUploadAlarm.LastError = "Wunderground: HTTP response - " + response.StatusCode; + HttpUploadAlarm.LastMessage = "Wunderground: HTTP response - " + response.StatusCode; HttpUploadAlarm.Triggered = true; Wund.ErrorFlagCount = 0; } @@ -2260,7 +2262,7 @@ internal async void UpdateWunderground(DateTime timestamp) catch (Exception ex) { LogMessage("Wunderground: ERROR - " + ex.Message); - HttpUploadAlarm.LastError = "Wunderground: " + ex.Message; + HttpUploadAlarm.LastMessage = "Wunderground: " + ex.Message; HttpUploadAlarm.Triggered = true; } finally @@ -2294,7 +2296,7 @@ internal async void UpdateWindy(DateTime timestamp) if (response.StatusCode != HttpStatusCode.OK) { LogMessage("Windy: ERROR - Response = " + response.StatusCode + ": " + responseBodyAsText); - HttpUploadAlarm.LastError = "Windy: HTTP response - " + response.StatusCode; + HttpUploadAlarm.LastMessage = "Windy: HTTP response - " + response.StatusCode; HttpUploadAlarm.Triggered = true; } else @@ -2306,7 +2308,7 @@ internal async void UpdateWindy(DateTime timestamp) catch (Exception ex) { LogMessage("Windy: ERROR - " + ex.Message); - HttpUploadAlarm.LastError = "Windy: " + ex.Message; + HttpUploadAlarm.LastMessage = "Windy: " + ex.Message; HttpUploadAlarm.Triggered = true; } finally @@ -2340,7 +2342,7 @@ internal async void UpdateWindGuru(DateTime timestamp) if (response.StatusCode != HttpStatusCode.OK) { LogMessage("WindGuru: ERROR - " + response.StatusCode + ": " + responseBodyAsText); - HttpUploadAlarm.LastError = "WindGuru: HTTP response - " + response.StatusCode; + HttpUploadAlarm.LastMessage = "WindGuru: HTTP response - " + response.StatusCode; HttpUploadAlarm.Triggered = true; } else @@ -2352,7 +2354,7 @@ internal async void UpdateWindGuru(DateTime timestamp) catch (Exception ex) { LogMessage("WindGuru: ERROR - " + ex.Message); - HttpUploadAlarm.LastError = "WindGuru: " + ex.Message; + HttpUploadAlarm.LastMessage = "WindGuru: " + ex.Message; HttpUploadAlarm.Triggered = true; } finally @@ -2392,7 +2394,7 @@ internal async void UpdateAwekas(DateTime timestamp) if (response.StatusCode != HttpStatusCode.OK) { LogMessage($"AWEKAS: ERROR - Response code = {response.StatusCode}, body = {responseBodyAsText}"); - HttpUploadAlarm.LastError = $"AWEKAS: HTTP Response code = {response.StatusCode}, body = {responseBodyAsText}"; + HttpUploadAlarm.LastMessage = $"AWEKAS: HTTP Response code = {response.StatusCode}, body = {responseBodyAsText}"; HttpUploadAlarm.Triggered = true; AWEKAS.Updating = false; return; @@ -2411,7 +2413,7 @@ internal async void UpdateAwekas(DateTime timestamp) { LogMessage("AWEKAS: Exception deserializing response = " + ex.Message); LogMessage($"AWEKAS: ERROR - Response body = {responseBodyAsText}"); - HttpUploadAlarm.LastError = "AWEKAS deserializing response: " + ex.Message; + HttpUploadAlarm.LastMessage = "AWEKAS deserializing response: " + ex.Message; HttpUploadAlarm.Triggered = true; AWEKAS.Updating = false; return; @@ -2469,7 +2471,7 @@ internal async void UpdateAwekas(DateTime timestamp) else { LogMessage("AWEKAS: Unknown error"); - HttpUploadAlarm.LastError = "AWEKAS: Unknown error"; + HttpUploadAlarm.LastMessage = "AWEKAS: Unknown error"; HttpUploadAlarm.Triggered = true; } } @@ -2504,7 +2506,7 @@ internal async void UpdateAwekas(DateTime timestamp) catch (Exception ex) { LogMessage("AWEKAS: Exception = " + ex.Message); - HttpUploadAlarm.LastError = "AWEKAS: " + ex.Message; + HttpUploadAlarm.LastMessage = "AWEKAS: " + ex.Message; HttpUploadAlarm.Triggered = true; } finally @@ -2546,27 +2548,27 @@ internal async void UpdateWCloud(DateTime timestamp) break; case 400: msg = "Bad request"; - HttpUploadAlarm.LastError = "WeatherCloud: " + msg; + HttpUploadAlarm.LastMessage = "WeatherCloud: " + msg; HttpUploadAlarm.Triggered = true; break; case 401: msg = "Incorrect WID or Key"; - HttpUploadAlarm.LastError = "WeatherCloud: " + msg; + HttpUploadAlarm.LastMessage = "WeatherCloud: " + msg; HttpUploadAlarm.Triggered = true; break; case 429: msg = "Too many requests"; - HttpUploadAlarm.LastError = "WeatherCloud: " + msg; + HttpUploadAlarm.LastMessage = "WeatherCloud: " + msg; HttpUploadAlarm.Triggered = true; break; case 500: msg = "Server error"; - HttpUploadAlarm.LastError = "WeatherCloud: " + msg; + HttpUploadAlarm.LastMessage = "WeatherCloud: " + msg; HttpUploadAlarm.Triggered = true; break; default: msg = "Unknown error"; - HttpUploadAlarm.LastError = "WeatherCloud: " + msg; + HttpUploadAlarm.LastMessage = "WeatherCloud: " + msg; HttpUploadAlarm.Triggered = true; break; } @@ -2579,7 +2581,7 @@ internal async void UpdateWCloud(DateTime timestamp) catch (Exception ex) { LogMessage("WeatherCloud: ERROR - " + ex.Message); - HttpUploadAlarm.LastError = "WeatherCloud: " + ex.Message; + HttpUploadAlarm.LastMessage = "WeatherCloud: " + ex.Message; HttpUploadAlarm.Triggered = true; } finally @@ -2617,7 +2619,7 @@ internal async void UpdateOpenWeatherMap(DateTime timestamp) if (response.StatusCode != HttpStatusCode.NoContent) { LogMessage($"OpenWeatherMap: ERROR - Response code = {response.StatusCode}, Response data = {responseBodyAsText}"); - HttpUploadAlarm.LastError = $"OpenWeatherMap: HTTP response - {response.StatusCode}, Response data = {responseBodyAsText}"; + HttpUploadAlarm.LastMessage = $"OpenWeatherMap: HTTP response - {response.StatusCode}, Response data = {responseBodyAsText}"; HttpUploadAlarm.Triggered = true; } else @@ -2629,7 +2631,7 @@ internal async void UpdateOpenWeatherMap(DateTime timestamp) catch (Exception ex) { LogMessage("OpenWeatherMap: ERROR - " + ex.Message); - HttpUploadAlarm.LastError = "OpenWeatherMap: " + ex.Message; + HttpUploadAlarm.LastMessage = "OpenWeatherMap: " + ex.Message; HttpUploadAlarm.Triggered = true; } finally @@ -5370,6 +5372,15 @@ private void ReadIniFile() MySqlUploadAlarm.Action = ini.GetValue("Alarms", "MySqlUploadAlarmAction", ""); MySqlUploadAlarm.ActionParams = ini.GetValue("Alarms", "MySqlUploadAlarmActionParams", ""); + NewRecordAlarm.Enabled = ini.GetValue("Alarms", "NewRecordAlarmSet", true); + NewRecordAlarm.Sound = ini.GetValue("Alarms", "NewRecordAlarmSound", false); + NewRecordAlarm.SoundFile = ini.GetValue("Alarms", "NewRecordAlarmSoundFile", DefaultSoundFile); + NewRecordAlarm.Notify = ini.GetValue("Alarms", "NewRecordAlarmNotify", false); + NewRecordAlarm.Email = ini.GetValue("Alarms", "NewRecordAlarmEmail", false); + NewRecordAlarm.Latch = ini.GetValue("Alarms", "NewRecordAlarmLatch", false); + NewRecordAlarm.LatchHours = ini.GetValue("Alarms", "NewRecordAlarmLatchHours", 24); + NewRecordAlarm.Action = ini.GetValue("Alarms", "NewRecordAlarmAction", ""); + NewRecordAlarm.ActionParams = ini.GetValue("Alarms", "NewRecordAlarmActionParams", ""); AlarmFromEmail = ini.GetValue("Alarms", "FromEmail", ""); AlarmDestEmail = ini.GetValue("Alarms", "DestEmail", "").Split(';'); @@ -6532,6 +6543,16 @@ internal void WriteIniFile() ini.SetValue("Alarms", "MySqlUploadAlarmAction", MySqlUploadAlarm.Action); ini.SetValue("Alarms", "MySqlUploadAlarmActionParams", MySqlUploadAlarm.ActionParams); + ini.SetValue("Alarms", "NewRecordAlarmSet", NewRecordAlarm.Enabled); + ini.SetValue("Alarms", "NewRecordAlarmSound", NewRecordAlarm.Sound); + ini.SetValue("Alarms", "NewRecordAlarmSoundFile", NewRecordAlarm.SoundFile); + ini.SetValue("Alarms", "NewRecordAlarmNotify", NewRecordAlarm.Notify); + ini.SetValue("Alarms", "NewRecordAlarmEmail", NewRecordAlarm.Email); + ini.SetValue("Alarms", "NewRecordAlarmLatch", NewRecordAlarm.Latch); + ini.SetValue("Alarms", "NewRecordAlarmLatchHours", NewRecordAlarm.LatchHours); + ini.SetValue("Alarms", "NewRecordAlarmAction", NewRecordAlarm.Action); + ini.SetValue("Alarms", "NewRecordAlarmActionParams", NewRecordAlarm.ActionParams); + ini.SetValue("Alarms", "FromEmail", AlarmFromEmail); ini.SetValue("Alarms", "DestEmail", AlarmDestEmail.Join(";")); ini.SetValue("Alarms", "UseHTML", AlarmEmailHtml); @@ -7102,6 +7123,7 @@ private void ReadStringsFile() HttpUploadAlarm.EmailMsg = ini.GetValue("AlarmEmails", "httpStopped", "HTTP uploads are failing."); MySqlUploadAlarm.EmailMsg = ini.GetValue("AlarmEmails", "mySqlStopped", "MySQL uploads are failing."); IsRainingAlarm.EmailMsg = ini.GetValue("AlarmEmails", "isRaining", "It has started to rain."); + NewRecordAlarm.EmailMsg = ini.GetValue("AlarmEmails", "newRecord", "A new all-time record has been set."); if (!File.Exists("strings.ini")) { @@ -12563,7 +12585,7 @@ public async void UpdatePWSweather(DateTime timestamp) if (response.StatusCode != HttpStatusCode.OK) { LogMessage($"PWS Response: ERROR - Response code = {response.StatusCode}, Body = {responseBodyAsText}"); - HttpUploadAlarm.LastError = $"PWS: HTTP Response code = {response.StatusCode}, Body = {responseBodyAsText}"; + HttpUploadAlarm.LastMessage = $"PWS: HTTP Response code = {response.StatusCode}, Body = {responseBodyAsText}"; HttpUploadAlarm.Triggered = true; } else @@ -12576,7 +12598,7 @@ public async void UpdatePWSweather(DateTime timestamp) catch (Exception ex) { LogMessage("PWS update: " + ex.Message); - HttpUploadAlarm.LastError = "PWS: " + ex.Message; + HttpUploadAlarm.LastMessage = "PWS: " + ex.Message; HttpUploadAlarm.Triggered = true; } finally @@ -12608,7 +12630,7 @@ public async void UpdateWOW(DateTime timestamp) if (response.StatusCode != HttpStatusCode.OK) { LogMessage($"WOW Response: ERROR - Response code = {response.StatusCode}, body = {responseBodyAsText}"); - HttpUploadAlarm.LastError = $"WOW: HTTP response - Response code = {response.StatusCode}, body = {responseBodyAsText}"; + HttpUploadAlarm.LastMessage = $"WOW: HTTP response - Response code = {response.StatusCode}, body = {responseBodyAsText}"; HttpUploadAlarm.Triggered = true; } else @@ -12621,7 +12643,7 @@ public async void UpdateWOW(DateTime timestamp) catch (Exception ex) { LogMessage("WOW update: " + ex.Message); - HttpUploadAlarm.LastError = "WOW: " + ex.Message; + HttpUploadAlarm.LastMessage = "WOW: " + ex.Message; HttpUploadAlarm.Triggered = true; } finally @@ -12717,7 +12739,7 @@ await Task.Run(() => } - MySqlUploadAlarm.LastError = ex.Message; + MySqlUploadAlarm.LastMessage = ex.Message; MySqlUploadAlarm.Triggered = true; if (MySqlSettings.BufferOnfailure && !UseFailedList) @@ -12805,7 +12827,7 @@ public void MySqlCommandSync(ConcurrentQueue Cmds, string CallingFunct LogMessage($"{CallingFunction}: SQL = {cachedCmd}"); } - MySqlUploadAlarm.LastError = ex.Message; + MySqlUploadAlarm.LastMessage = ex.Message; MySqlUploadAlarm.Triggered = true; // do we save this command/commands on failure to be resubmitted? @@ -12900,7 +12922,7 @@ public async void GetLatestVersion() var msg = $"You are not running the latest version of Cumulus MX, build {LatestBuild} is available."; LogConsoleMessage(msg, ConsoleColor.Cyan); LogMessage(msg); - UpgradeAlarm.LastError = $"Build {LatestBuild} is available"; + UpgradeAlarm.LastMessage = $"Build {LatestBuild} is available"; UpgradeAlarm.Triggered = true; } else if (int.Parse(Build) == int.Parse(LatestBuild)) diff --git a/CumulusMX/CumulusMX.csproj b/CumulusMX/CumulusMX.csproj index da44e3d0..846a2c90 100644 --- a/CumulusMX/CumulusMX.csproj +++ b/CumulusMX/CumulusMX.csproj @@ -233,7 +233,7 @@ 3.5.2 - 46.0.2 + 47.0.0 2.1.0 @@ -245,7 +245,7 @@ 4.2.1.781 - 2.2.6 + 2.2.7 2.2.5 diff --git a/CumulusMX/DavisStation.cs b/CumulusMX/DavisStation.cs index 68e60fb5..a48b980d 100644 --- a/CumulusMX/DavisStation.cs +++ b/CumulusMX/DavisStation.cs @@ -1978,7 +1978,7 @@ private void GetAndProcessLoop2Data(int number) cumulus.LogSpikeRemoval("Station Pressure difference greater than specified; reading ignored"); cumulus.LogSpikeRemoval($"NewVal={pressMB:F1} OldVal={previousPressStation:F1} SpikePressDiff={cumulus.Spike.PressDiff:F1} HighLimit={cumulus.Limit.PressHigh:F1} LowLimit={cumulus.Limit.PressLow:F1}"); lastSpikeRemoval = DateTime.Now; - cumulus.SpikeAlarm.LastError = $"Station Pressure difference greater than spike value - NewVal={pressMB:F1} OldVal={previousPressStation:F1}"; + cumulus.SpikeAlarm.LastMessage = $"Station Pressure difference greater than spike value - NewVal={pressMB:F1} OldVal={previousPressStation:F1}"; cumulus.SpikeAlarm.Triggered = true; } } diff --git a/CumulusMX/DavisWllStation.cs b/CumulusMX/DavisWllStation.cs index d9118e4b..4562ba9e 100644 --- a/CumulusMX/DavisWllStation.cs +++ b/CumulusMX/DavisWllStation.cs @@ -534,7 +534,7 @@ private async void GetWllCurrent(object source, ElapsedEventArgs e) DataStopped = true; DataStoppedTime = DateTime.Now; - cumulus.DataStoppedAlarm.LastError = "No current data is being received from the WLL"; + cumulus.DataStoppedAlarm.LastMessage = "No current data is being received from the WLL"; cumulus.DataStoppedAlarm.Triggered = true; } } @@ -3208,7 +3208,7 @@ private void BroadcastTimeout(object source, ElapsedEventArgs e) { DataStoppedTime = DateTime.Now; } - cumulus.DataStoppedAlarm.LastError = $"No broadcast data received from the WLL for {tmrBroadcastWatchdog.Interval / 1000} seconds"; + cumulus.DataStoppedAlarm.LastMessage = $"No broadcast data received from the WLL for {tmrBroadcastWatchdog.Interval / 1000} seconds"; cumulus.DataStoppedAlarm.Triggered = true; broadcastStopped = true; // Try and give the broadcasts a kick in case the last command did not get through diff --git a/CumulusMX/FOStation.cs b/CumulusMX/FOStation.cs index c793ea94..e18c3d86 100644 --- a/CumulusMX/FOStation.cs +++ b/CumulusMX/FOStation.cs @@ -717,7 +717,7 @@ private bool ReadAddress(int address, byte[] buff) } DataStopped = true; - cumulus.DataStoppedAlarm.LastError = "USB device no longer detected"; + cumulus.DataStoppedAlarm.LastMessage = "USB device no longer detected"; cumulus.DataStoppedAlarm.Triggered = true; return false; } @@ -737,7 +737,7 @@ private bool ReadAddress(int address, byte[] buff) DataStoppedTime = DateTime.Now; } DataStopped = true; - cumulus.DataStoppedAlarm.LastError = "Error reading data from station - it may need resetting. " + ex.Message; + cumulus.DataStoppedAlarm.LastMessage = "Error reading data from station - it may need resetting. " + ex.Message; cumulus.DataStoppedAlarm.Triggered = true; return false; } @@ -760,7 +760,7 @@ private bool ReadAddress(int address, byte[] buff) DataStoppedTime = DateTime.Now; } DataStopped = true; - cumulus.DataStoppedAlarm.LastError = "Error reading data from station - it may need resetting. " + ex.Message; + cumulus.DataStoppedAlarm.LastMessage = "Error reading data from station - it may need resetting. " + ex.Message; cumulus.DataStoppedAlarm.Triggered = true; return false; } @@ -802,7 +802,7 @@ private bool WriteAddress(int address, byte val) DataStoppedTime = DateTime.Now; } DataStopped = true; - cumulus.DataStoppedAlarm.LastError = "Error sending command to station - it may need resetting: " + ex.Message; + cumulus.DataStoppedAlarm.LastMessage = "Error sending command to station - it may need resetting: " + ex.Message; cumulus.DataStoppedAlarm.Triggered = true; return false; } diff --git a/CumulusMX/GW1000Station.cs b/CumulusMX/GW1000Station.cs index 6805751c..80d5de4f 100644 --- a/CumulusMX/GW1000Station.cs +++ b/CumulusMX/GW1000Station.cs @@ -1680,7 +1680,7 @@ private void DataTimeout(object source, ElapsedEventArgs e) DataStoppedTime = DateTime.Now; DataStopped = true; } - cumulus.DataStoppedAlarm.LastError = $"No data received from the GW1000 for {tmrDataWatchdog.Interval / 1000} seconds"; + cumulus.DataStoppedAlarm.LastMessage = $"No data received from the GW1000 for {tmrDataWatchdog.Interval / 1000} seconds"; cumulus.DataStoppedAlarm.Triggered = true; if (DoDiscovery()) { diff --git a/CumulusMX/LangSettings.cs b/CumulusMX/LangSettings.cs index a383e6d1..cd8f4be7 100644 --- a/CumulusMX/LangSettings.cs +++ b/CumulusMX/LangSettings.cs @@ -130,7 +130,8 @@ public string GetAlpacaFormData() dataSpike = cumulus.SpikeAlarm.EmailMsg, upgrade = cumulus.UpgradeAlarm.EmailMsg, httpStopped = cumulus.HttpUploadAlarm.EmailMsg, - mySqlStopped = cumulus.MySqlUploadAlarm.EmailMsg + mySqlStopped = cumulus.MySqlUploadAlarm.EmailMsg, + newRecord = cumulus.NewRecordAlarm.EmailMsg }; var settings = new Settings() @@ -378,6 +379,7 @@ public string UpdateConfig(IHttpContext context) cumulus.UpgradeAlarm.EmailMsg = settings.alarms.upgrade.Trim(); cumulus.HttpUploadAlarm.EmailMsg = settings.alarms.httpStopped.Trim(); cumulus.MySqlUploadAlarm.EmailMsg = settings.alarms.mySqlStopped.Trim(); + cumulus.NewRecordAlarm.EmailMsg = settings.alarms.newRecord.Trim(); } catch (Exception ex) { @@ -505,6 +507,7 @@ private class AlarmEmails public string upgrade { get; set; } public string httpStopped { get; set; } public string mySqlStopped { get; set; } + public string newRecord { get; set; } } private class Settings diff --git a/CumulusMX/WeatherStation.cs b/CumulusMX/WeatherStation.cs index 1ab2571a..f5daf2b9 100644 --- a/CumulusMX/WeatherStation.cs +++ b/CumulusMX/WeatherStation.cs @@ -1596,65 +1596,25 @@ private void RemoveOldRecentData(DateTime ts) private void ClearAlarms() { - if (cumulus.DataStoppedAlarm.Latch && cumulus.DataStoppedAlarm.Triggered && DateTime.Now > cumulus.DataStoppedAlarm.TriggeredTime.AddHours(cumulus.DataStoppedAlarm.LatchHours)) - cumulus.DataStoppedAlarm.Triggered = false; - - if (cumulus.BatteryLowAlarm.Latch && cumulus.BatteryLowAlarm.Triggered && DateTime.Now > cumulus.BatteryLowAlarm.TriggeredTime.AddHours(cumulus.BatteryLowAlarm.LatchHours)) - cumulus.BatteryLowAlarm.Triggered = false; - - if (cumulus.SensorAlarm.Latch && cumulus.SensorAlarm.Triggered && DateTime.Now > cumulus.SensorAlarm.TriggeredTime.AddHours(cumulus.SensorAlarm.LatchHours)) - cumulus.SensorAlarm.Triggered = false; - - if (cumulus.SpikeAlarm.Latch && cumulus.SpikeAlarm.Triggered && DateTime.Now > cumulus.SpikeAlarm.TriggeredTime.AddHours(cumulus.SpikeAlarm.LatchHours)) - cumulus.SpikeAlarm.Triggered = false; - - if (cumulus.UpgradeAlarm.Latch && cumulus.UpgradeAlarm.Triggered && DateTime.Now > cumulus.UpgradeAlarm.TriggeredTime.AddHours(cumulus.UpgradeAlarm.LatchHours)) - cumulus.UpgradeAlarm.Triggered = false; - - if (cumulus.HttpUploadAlarm.Latch && cumulus.HttpUploadAlarm.Triggered && DateTime.Now > cumulus.HttpUploadAlarm.TriggeredTime.AddHours(cumulus.HttpUploadAlarm.LatchHours)) - cumulus.HttpUploadAlarm.Triggered = false; - - if (cumulus.MySqlUploadAlarm.Latch && cumulus.MySqlUploadAlarm.Triggered && DateTime.Now > cumulus.MySqlUploadAlarm.TriggeredTime.AddHours(cumulus.MySqlUploadAlarm.LatchHours)) - cumulus.MySqlUploadAlarm.Triggered = false; - - if (cumulus.HighWindAlarm.Latch && cumulus.HighWindAlarm.Triggered && DateTime.Now > cumulus.HighWindAlarm.TriggeredTime.AddHours(cumulus.HighWindAlarm.LatchHours)) - cumulus.HighWindAlarm.Triggered = false; - - if (cumulus.HighGustAlarm.Latch && cumulus.HighGustAlarm.Triggered && DateTime.Now > cumulus.HighGustAlarm.TriggeredTime.AddHours(cumulus.HighGustAlarm.LatchHours)) - cumulus.HighGustAlarm.Triggered = false; - - if (cumulus.HighRainRateAlarm.Latch && cumulus.HighRainRateAlarm.Triggered && DateTime.Now > cumulus.HighRainRateAlarm.TriggeredTime.AddHours(cumulus.HighRainRateAlarm.LatchHours)) - cumulus.HighRainRateAlarm.Triggered = false; - - if (cumulus.HighRainTodayAlarm.Latch && cumulus.HighRainTodayAlarm.Triggered && DateTime.Now > cumulus.HighRainTodayAlarm.TriggeredTime.AddHours(cumulus.HighRainTodayAlarm.LatchHours)) - cumulus.HighRainTodayAlarm.Triggered = false; - - if (cumulus.IsRainingAlarm.Latch && cumulus.IsRainingAlarm.Triggered && DateTime.Now > cumulus.IsRainingAlarm.TriggeredTime.AddHours(cumulus.IsRainingAlarm.LatchHours)) - cumulus.IsRainingAlarm.Triggered = false; - - if (cumulus.HighPressAlarm.Latch && cumulus.HighPressAlarm.Triggered && DateTime.Now > cumulus.HighPressAlarm.TriggeredTime.AddHours(cumulus.HighPressAlarm.LatchHours)) - cumulus.HighPressAlarm.Triggered = false; - - if (cumulus.LowPressAlarm.Latch && cumulus.LowPressAlarm.Triggered && DateTime.Now > cumulus.LowPressAlarm.TriggeredTime.AddHours(cumulus.LowPressAlarm.LatchHours)) - cumulus.LowPressAlarm.Triggered = false; - - if (cumulus.HighTempAlarm.Latch && cumulus.HighTempAlarm.Triggered && DateTime.Now > cumulus.HighTempAlarm.TriggeredTime.AddHours(cumulus.HighTempAlarm.LatchHours)) - cumulus.HighTempAlarm.Triggered = false; - - if (cumulus.LowTempAlarm.Latch && cumulus.LowTempAlarm.Triggered && DateTime.Now > cumulus.LowTempAlarm.TriggeredTime.AddHours(cumulus.LowTempAlarm.LatchHours)) - cumulus.LowTempAlarm.Triggered = false; - - if (cumulus.TempChangeAlarm.Latch && cumulus.TempChangeAlarm.UpTriggered && DateTime.Now > cumulus.TempChangeAlarm.UpTriggeredTime.AddHours(cumulus.TempChangeAlarm.LatchHours)) - cumulus.TempChangeAlarm.UpTriggered = false; - - if (cumulus.TempChangeAlarm.Latch && cumulus.TempChangeAlarm.DownTriggered && DateTime.Now > cumulus.TempChangeAlarm.DownTriggeredTime.AddHours(cumulus.TempChangeAlarm.LatchHours)) - cumulus.TempChangeAlarm.DownTriggered = false; - - if (cumulus.PressChangeAlarm.Latch && cumulus.PressChangeAlarm.UpTriggered && DateTime.Now > cumulus.PressChangeAlarm.UpTriggeredTime.AddHours(cumulus.PressChangeAlarm.LatchHours)) - cumulus.PressChangeAlarm.UpTriggered = false; - - if (cumulus.PressChangeAlarm.Latch && cumulus.PressChangeAlarm.DownTriggered && DateTime.Now > cumulus.PressChangeAlarm.DownTriggeredTime.AddHours(cumulus.PressChangeAlarm.LatchHours)) - cumulus.PressChangeAlarm.DownTriggered = false; + cumulus.DataStoppedAlarm.ClearAlarm(); + cumulus.BatteryLowAlarm.ClearAlarm(); + cumulus.NewRecordAlarm.ClearAlarm(); + cumulus.SensorAlarm.ClearAlarm(); + cumulus.SpikeAlarm.ClearAlarm(); + cumulus.UpgradeAlarm.ClearAlarm(); + cumulus.HttpUploadAlarm.ClearAlarm(); + cumulus.MySqlUploadAlarm.ClearAlarm(); + cumulus.HighWindAlarm.ClearAlarm(); + cumulus.HighGustAlarm.ClearAlarm(); + cumulus.HighRainRateAlarm.ClearAlarm(); + cumulus.HighRainTodayAlarm.ClearAlarm(); + cumulus.IsRainingAlarm.ClearAlarm(); + cumulus.HighPressAlarm.ClearAlarm(); + cumulus.LowPressAlarm.ClearAlarm(); + cumulus.HighTempAlarm.ClearAlarm(); + cumulus.LowTempAlarm.ClearAlarm(); + cumulus.TempChangeAlarm.ClearAlarm(); + cumulus.PressChangeAlarm.ClearAlarm(); } private void MinuteChanged(DateTime now) @@ -4102,6 +4062,8 @@ public string CreateWxnowFileString() data += APRSsolarradStr(SolarRad); } + + return data; } @@ -4277,7 +4239,7 @@ public void DoIndoorHumidity(int hum) cumulus.LogSpikeRemoval("Indoor humidity difference greater than specified; reading ignored"); cumulus.LogSpikeRemoval($"NewVal={hum} OldVal={previousInHum} SpikeDiff={cumulus.Spike.InHumDiff:F1}"); lastSpikeRemoval = DateTime.Now; - cumulus.SpikeAlarm.LastError = $"Indoor humidity difference greater than spike value - NewVal={hum} OldVal={previousInHum}"; + cumulus.SpikeAlarm.LastMessage = $"Indoor humidity difference greater than spike value - NewVal={hum} OldVal={previousInHum}"; cumulus.SpikeAlarm.Triggered = true; return; } @@ -4294,7 +4256,7 @@ public void DoIndoorTemp(double temp) cumulus.LogSpikeRemoval("Indoor temperature difference greater than specified; reading ignored"); cumulus.LogSpikeRemoval($"NewVal={temp} OldVal={previousInTemp} SpikeDiff={cumulus.Spike.InTempDiff:F1}"); lastSpikeRemoval = DateTime.Now; - cumulus.SpikeAlarm.LastError = $"Indoor temperature difference greater than spike value - NewVal={temp} OldVal={previousInTemp}"; + cumulus.SpikeAlarm.LastMessage = $"Indoor temperature difference greater than spike value - NewVal={temp} OldVal={previousInTemp}"; cumulus.SpikeAlarm.Triggered = true; return; } @@ -4311,7 +4273,7 @@ public void DoOutdoorHumidity(int humpar, DateTime timestamp) cumulus.LogSpikeRemoval("Humidity difference greater than specified; reading ignored"); cumulus.LogSpikeRemoval($"NewVal={humpar} OldVal={previousHum} SpikeHumidityDiff={cumulus.Spike.HumidityDiff:F1}"); lastSpikeRemoval = DateTime.Now; - cumulus.SpikeAlarm.LastError = $"Humidity difference greater than spike value - NewVal={humpar} OldVal={previousHum}"; + cumulus.SpikeAlarm.LastMessage = $"Humidity difference greater than spike value - NewVal={humpar} OldVal={previousHum}"; cumulus.SpikeAlarm.Triggered = true; return; } @@ -4396,7 +4358,7 @@ public void DoOutdoorTemp(double temp, DateTime timestamp) tempC >= cumulus.Limit.TempHigh || tempC <= cumulus.Limit.TempLow) { lastSpikeRemoval = DateTime.Now; - cumulus.SpikeAlarm.LastError = $"Temp difference greater than spike value - NewVal={tempC.ToString(cumulus.TempFormat)} OldVal={previousTemp.ToString(cumulus.TempFormat)}"; + cumulus.SpikeAlarm.LastMessage = $"Temp difference greater than spike value - NewVal={tempC.ToString(cumulus.TempFormat)} OldVal={previousTemp.ToString(cumulus.TempFormat)}"; cumulus.SpikeAlarm.Triggered = true; cumulus.LogSpikeRemoval("Temp difference greater than specified; reading ignored"); cumulus.LogSpikeRemoval($"NewVal={tempC.ToString(cumulus.TempFormat)} OldVal={previousTemp.ToString(cumulus.TempFormat)} SpikeTempDiff={cumulus.Spike.TempDiff.ToString(cumulus.TempFormat)} HighLimit={cumulus.Limit.TempHigh.ToString(cumulus.TempFormat)} LowLimit={cumulus.Limit.TempLow.ToString(cumulus.TempFormat)}"); @@ -4849,7 +4811,7 @@ public void DoPressure(double sl, DateTime timestamp) cumulus.LogSpikeRemoval("Pressure difference greater than specified; reading ignored"); cumulus.LogSpikeRemoval($"NewVal={pressMB:F1} OldVal={previousPress:F1} SpikePressDiff={cumulus.Spike.PressDiff:F1} HighLimit={cumulus.Limit.PressHigh:F1} LowLimit={cumulus.Limit.PressLow:F1}"); lastSpikeRemoval = DateTime.Now; - cumulus.SpikeAlarm.LastError = $"Pressure difference greater than spike value - NewVal={pressMB:F1} OldVal={previousPress:F1}"; + cumulus.SpikeAlarm.LastMessage = $"Pressure difference greater than spike value - NewVal={pressMB:F1} OldVal={previousPress:F1}"; cumulus.SpikeAlarm.Triggered = true; return; } @@ -4967,7 +4929,7 @@ public void DoRain(double total, double rate, DateTime timestamp) cumulus.LogSpikeRemoval("Rain rate greater than specified; reading ignored"); cumulus.LogSpikeRemoval($"Rate value = {rainRateMM:F2} SpikeMaxRainRate = {cumulus.Spike.MaxRainRate:F2}"); lastSpikeRemoval = DateTime.Now; - cumulus.SpikeAlarm.LastError = $"Rain rate greater than spike value - value = {rainRateMM:F2}mm/hr"; + cumulus.SpikeAlarm.LastMessage = $"Rain rate greater than spike value - value = {rainRateMM:F2}mm/hr"; cumulus.SpikeAlarm.Triggered = true; return; } @@ -5228,7 +5190,7 @@ public void DoOutdoorDewpoint(double dp, DateTime timestamp) { var msg = $"Dew point greater than limit ({cumulus.Limit.DewHigh.ToString(cumulus.TempFormat)}); reading ignored: {dp.ToString(cumulus.TempFormat)}"; lastSpikeRemoval = DateTime.Now; - cumulus.SpikeAlarm.LastError = msg; + cumulus.SpikeAlarm.LastMessage = msg; cumulus.SpikeAlarm.Triggered = true; cumulus.LogSpikeRemoval(msg); } @@ -5411,7 +5373,7 @@ public void DoWind(double gustpar, int bearingpar, double speedpar, DateTime tim cumulus.LogSpikeRemoval($"Gust: NewVal={windGustMS:F1} OldVal={previousGust:F1} SpikeGustDiff={cumulus.Spike.GustDiff:F1} HighLimit={cumulus.Limit.WindHigh:F1}"); cumulus.LogSpikeRemoval($"Wind: NewVal={windAvgMS:F1} OldVal={previousWind:F1} SpikeWindDiff={cumulus.Spike.WindDiff:F1}"); lastSpikeRemoval = DateTime.Now; - cumulus.SpikeAlarm.LastError = $"Wind or gust difference greater than spike/limit value - Gust: NewVal={windGustMS:F1}m/s OldVal={previousGust:F1}m/s - Wind: NewVal={windAvgMS:F1}m/s OldVal={previousWind:F1}m/s"; + cumulus.SpikeAlarm.LastMessage = $"Wind or gust difference greater than spike/limit value - Gust: NewVal={windGustMS:F1}m/s OldVal={previousGust:F1}m/s - Wind: NewVal={windAvgMS:F1}m/s OldVal={previousWind:F1}m/s"; cumulus.SpikeAlarm.Triggered = true; return; } @@ -5778,6 +5740,9 @@ public void SetAlltime(AllTimeRec rec, double value, DateTime timestamp) sb.Append(Environment.NewLine); File.AppendAllText(cumulus.Alltimelogfile, sb.ToString()); } + + cumulus.NewRecordAlarm.Triggered = true; + cumulus.NewRecordAlarm.LastMessage = rec.Desc + " = " + string.Format("{0,7:0.000}", value); } public void SetMonthlyAlltime(AllTimeRec rec, double value, DateTime timestamp) @@ -7725,7 +7690,7 @@ public void DoTrendValues(DateTime ts, bool rollover = false) // ignore cumulus.LogSpikeRemoval("Max hourly rainfall spike value exceed"); lastSpikeRemoval = DateTime.Now; - cumulus.SpikeAlarm.LastError = $"Max hourly rainfall greater than spike value - Value={tempRainLastHour:F1}"; + cumulus.SpikeAlarm.LastMessage = $"Max hourly rainfall greater than spike value - Value={tempRainLastHour:F1}"; cumulus.SpikeAlarm.Triggered = true; } else @@ -7801,7 +7766,7 @@ public void DoTrendValues(DateTime ts, bool rollover = false) cumulus.LogSpikeRemoval("Max rainfall rate spike value exceed"); cumulus.LogSpikeRemoval($"Rate value = {ConvertUserRainToMM(tempRainRate):F2} SpikeMaxRainRate = {cumulus.Spike.MaxRainRate:F2}"); lastSpikeRemoval = DateTime.Now; - cumulus.SpikeAlarm.LastError = $"Max rainfall rate greater than spike value - Value={tempRainRate:F1}"; + cumulus.SpikeAlarm.LastMessage = $"Max rainfall rate greater than spike value - Value={tempRainRate:F1}"; cumulus.SpikeAlarm.Triggered = true; } @@ -13978,7 +13943,7 @@ public bool CheckHighGust(double gust, int gustdir, DateTime timestamp) cumulus.LogSpikeRemoval("Wind Gust difference greater than specified; reading ignored"); cumulus.LogSpikeRemoval($"Gust: NewVal={windGustMS:F1} OldVal={previousGust:F1} SpikeGustDiff={cumulus.Spike.GustDiff:F1} HighLimit={cumulus.Limit.WindHigh:F1}"); lastSpikeRemoval = DateTime.Now; - cumulus.SpikeAlarm.LastError = $"Wind Gust difference greater than spike value - NewVal={windGustMS:F1}, OldVal={previousGust:F1}"; + cumulus.SpikeAlarm.LastMessage = $"Wind Gust difference greater than spike value - NewVal={windGustMS:F1}, OldVal={previousGust:F1}"; cumulus.SpikeAlarm.Triggered = true; return false; } diff --git a/Updates.txt b/Updates.txt index a896320d..fdbf0f31 100644 --- a/Updates.txt +++ b/Updates.txt @@ -18,6 +18,7 @@ Changed - MailKit, MQTTnet, MySqlConnector, ServiceStack - PHP upload now sends a text/plain content header - Davis WLL and Airlink now use the new simplified access method to weatherlink.com V2 API +- MX now persists the internal recent wind data across restarts Fixed - PWS passwords are now URL encoded @@ -29,6 +30,7 @@ Fixed - Updating MySQL on DayFile edits was erroring with a blank SQL statement + 3.25.2 - b3245 —————————————— Fixed From 886038787b6d273de4871899f2a802de72dc7c44 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Sun, 30 Jul 2023 18:27:50 +0100 Subject: [PATCH 21/27] Rename HTTP upload alarm to "third party" alarm Add FTP upload alarm Add wxnow.txt file comments --- CumulusMX/AlarmSettings.cs | 68 ++++--- CumulusMX/Cumulus.cs | 321 +++++++++++++++++++++++++--------- CumulusMX/DataEditor.cs | 10 +- CumulusMX/InternetSettings.cs | 6 +- CumulusMX/LangSettings.cs | 9 +- CumulusMX/WeatherStation.cs | 18 +- CumulusMX/webtags.cs | 4 +- Updates.txt | 4 +- 8 files changed, 322 insertions(+), 118 deletions(-) diff --git a/CumulusMX/AlarmSettings.cs b/CumulusMX/AlarmSettings.cs index 76426321..6749c9df 100644 --- a/CumulusMX/AlarmSettings.cs +++ b/CumulusMX/AlarmSettings.cs @@ -251,16 +251,16 @@ public string GetAlarmSettings() }, httpUpload = new JsonAlarmValues() { - Enabled = cumulus.HttpUploadAlarm.Enabled, - SoundEnabled = cumulus.HttpUploadAlarm.Sound, - Sound = cumulus.HttpUploadAlarm.SoundFile, - Notify = cumulus.HttpUploadAlarm.Notify, - Email = cumulus.HttpUploadAlarm.Email, - Latches = cumulus.HttpUploadAlarm.Latch, - LatchHrs = cumulus.HttpUploadAlarm.LatchHours, - Threshold = cumulus.HttpUploadAlarm.TriggerThreshold, - Action = cumulus.HttpUploadAlarm.Action, - ActionParams = cumulus.HttpUploadAlarm.ActionParams + Enabled = cumulus.ThirdPartyAlarm.Enabled, + SoundEnabled = cumulus.ThirdPartyAlarm.Sound, + Sound = cumulus.ThirdPartyAlarm.SoundFile, + Notify = cumulus.ThirdPartyAlarm.Notify, + Email = cumulus.ThirdPartyAlarm.Email, + Latches = cumulus.ThirdPartyAlarm.Latch, + LatchHrs = cumulus.ThirdPartyAlarm.LatchHours, + Threshold = cumulus.ThirdPartyAlarm.TriggerThreshold, + Action = cumulus.ThirdPartyAlarm.Action, + ActionParams = cumulus.ThirdPartyAlarm.ActionParams }, mySqlUpload = new JsonAlarmValues() { @@ -274,6 +274,19 @@ public string GetAlarmSettings() Threshold = cumulus.MySqlUploadAlarm.TriggerThreshold, Action = cumulus.MySqlUploadAlarm.Action, ActionParams = cumulus.MySqlUploadAlarm.ActionParams + }, + ftpUpload = new JsonAlarmValues() + { + Enabled = cumulus.FtpAlarm.Enabled, + SoundEnabled = cumulus.FtpAlarm.Sound, + Sound = cumulus.FtpAlarm.SoundFile, + Notify = cumulus.FtpAlarm.Notify, + Email = cumulus.FtpAlarm.Email, + Latches = cumulus.FtpAlarm.Latch, + LatchHrs = cumulus.FtpAlarm.LatchHours, + Threshold = cumulus.FtpAlarm.TriggerThreshold, + Action = cumulus.FtpAlarm.Action, + ActionParams = cumulus.FtpAlarm.ActionParams } }; @@ -533,17 +546,17 @@ public string UpdateAlarmSettings(IHttpContext context) cumulus.UpgradeAlarm.Action = settings.upgrade.Action.Trim(); cumulus.UpgradeAlarm.ActionParams = settings.upgrade.ActionParams.Trim(); - cumulus.HttpUploadAlarm.Enabled = settings.httpUpload.Enabled; - cumulus.HttpUploadAlarm.Sound = settings.httpUpload.SoundEnabled; - cumulus.HttpUploadAlarm.SoundFile = settings.httpUpload.Sound.Trim(); - cumulus.HttpUploadAlarm.Notify = settings.httpUpload.Notify; - cumulus.HttpUploadAlarm.Email = settings.httpUpload.Email; - cumulus.HttpUploadAlarm.Latch = settings.httpUpload.Latches; - cumulus.HttpUploadAlarm.LatchHours = settings.httpUpload.LatchHrs; - cumulus.HttpUploadAlarm.TriggerThreshold = settings.httpUpload.Threshold; - emailRequired = emailRequired || (cumulus.HttpUploadAlarm.Email && cumulus.HttpUploadAlarm.Enabled); - cumulus.HttpUploadAlarm.Action = settings.httpUpload.Action.Trim(); - cumulus.HttpUploadAlarm.ActionParams = settings.httpUpload.ActionParams.Trim(); + cumulus.ThirdPartyAlarm.Enabled = settings.httpUpload.Enabled; + cumulus.ThirdPartyAlarm.Sound = settings.httpUpload.SoundEnabled; + cumulus.ThirdPartyAlarm.SoundFile = settings.httpUpload.Sound.Trim(); + cumulus.ThirdPartyAlarm.Notify = settings.httpUpload.Notify; + cumulus.ThirdPartyAlarm.Email = settings.httpUpload.Email; + cumulus.ThirdPartyAlarm.Latch = settings.httpUpload.Latches; + cumulus.ThirdPartyAlarm.LatchHours = settings.httpUpload.LatchHrs; + cumulus.ThirdPartyAlarm.TriggerThreshold = settings.httpUpload.Threshold; + emailRequired = emailRequired || (cumulus.ThirdPartyAlarm.Email && cumulus.ThirdPartyAlarm.Enabled); + cumulus.ThirdPartyAlarm.Action = settings.httpUpload.Action.Trim(); + cumulus.ThirdPartyAlarm.ActionParams = settings.httpUpload.ActionParams.Trim(); cumulus.MySqlUploadAlarm.Enabled = settings.mySqlUpload.Enabled; cumulus.MySqlUploadAlarm.Sound = settings.mySqlUpload.SoundEnabled; @@ -557,6 +570,18 @@ public string UpdateAlarmSettings(IHttpContext context) cumulus.MySqlUploadAlarm.Action = settings.mySqlUpload.Action.Trim(); cumulus.MySqlUploadAlarm.ActionParams = settings.mySqlUpload.ActionParams.Trim(); + cumulus.FtpAlarm.Enabled = settings.ftpUpload.Enabled; + cumulus.FtpAlarm.Sound = settings.ftpUpload.SoundEnabled; + cumulus.FtpAlarm.SoundFile = settings.ftpUpload.Sound.Trim(); + cumulus.FtpAlarm.Notify = settings.ftpUpload.Notify; + cumulus.FtpAlarm.Email = settings.ftpUpload.Email; + cumulus.FtpAlarm.Latch = settings.ftpUpload.Latches; + cumulus.FtpAlarm.LatchHours = settings.ftpUpload.LatchHrs; + cumulus.FtpAlarm.TriggerThreshold = settings.ftpUpload.Threshold; + emailRequired = emailRequired || (cumulus.FtpAlarm.Email && cumulus.FtpAlarm.Enabled); + cumulus.FtpAlarm.Action = settings.ftpUpload.Action.Trim(); + cumulus.FtpAlarm.ActionParams = settings.ftpUpload.ActionParams.Trim(); + // validate the from email if (emailRequired && !EmailSender.CheckEmailAddress(result.email.fromEmail.Trim())) { @@ -684,6 +709,7 @@ public class JsonAlarmSettingsData public JsonAlarmValues httpUpload { get; set; } public JsonAlarmValues mySqlUpload { get; set; } public JsonAlarmValues isRaining { get; set; } + public JsonAlarmValues ftpUpload { get; set; } } public class JsonAlarmValues diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index 3fe634ad..0202a133 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -477,6 +477,7 @@ public struct TExtraFiles // OpenWeatherMap settings public WebUploadService OpenWeatherMap = new WebUploadService(); + public string WxnowComment = string.Empty; // MQTT settings public struct MqttSettings @@ -529,10 +530,11 @@ public struct MqttSettings public Alarm HighTempAlarm = new Alarm("High Temperature", AlarmTypes.Above); public Alarm LowTempAlarm = new Alarm("Low Temperature", AlarmTypes.Below); public Alarm UpgradeAlarm = new Alarm("Upgrade Available", AlarmTypes.Trigger); - public Alarm HttpUploadAlarm = new Alarm("HTTP Uploads", AlarmTypes.Trigger); + public Alarm ThirdPartyAlarm = new Alarm("HTTP Uploads", AlarmTypes.Trigger); public Alarm MySqlUploadAlarm = new Alarm("MySQL Uploads", AlarmTypes.Trigger); public Alarm IsRainingAlarm = new Alarm("IsRaining", AlarmTypes.Trigger); public Alarm NewRecordAlarm = new Alarm("New Record", AlarmTypes.Trigger); + public Alarm FtpAlarm = new Alarm("Web Upload", AlarmTypes.Trigger); private const double DEFAULTFCLOWPRESS = 950.0; @@ -1382,10 +1384,11 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) LowTempAlarm.cumulus = this; LowTempAlarm.Units = Units.TempText; UpgradeAlarm.cumulus = this; - HttpUploadAlarm.cumulus = this; + ThirdPartyAlarm.cumulus = this; MySqlUploadAlarm.cumulus = this; IsRainingAlarm.cumulus = this; NewRecordAlarm.cumulus = this; + FtpAlarm.cumulus = this; GetLatestVersion(); @@ -2247,14 +2250,14 @@ internal async void UpdateWunderground(DateTime timestamp) if (!Wund.RapidFireEnabled || Wund.ErrorFlagCount >= 12) { LogMessage("Wunderground: Response = " + response.StatusCode + ": " + responseBodyAsText); - HttpUploadAlarm.LastMessage = "Wunderground: HTTP response - " + response.StatusCode; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = "Wunderground: HTTP response - " + response.StatusCode; + ThirdPartyAlarm.Triggered = true; Wund.ErrorFlagCount = 0; } } else { - HttpUploadAlarm.Triggered = false; + ThirdPartyAlarm.Triggered = false; Wund.ErrorFlagCount = 0; } } @@ -2262,8 +2265,8 @@ internal async void UpdateWunderground(DateTime timestamp) catch (Exception ex) { LogMessage("Wunderground: ERROR - " + ex.Message); - HttpUploadAlarm.LastMessage = "Wunderground: " + ex.Message; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = "Wunderground: " + ex.Message; + ThirdPartyAlarm.Triggered = true; } finally { @@ -2296,20 +2299,20 @@ internal async void UpdateWindy(DateTime timestamp) if (response.StatusCode != HttpStatusCode.OK) { LogMessage("Windy: ERROR - Response = " + response.StatusCode + ": " + responseBodyAsText); - HttpUploadAlarm.LastMessage = "Windy: HTTP response - " + response.StatusCode; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = "Windy: HTTP response - " + response.StatusCode; + ThirdPartyAlarm.Triggered = true; } else { - HttpUploadAlarm.Triggered = false; + ThirdPartyAlarm.Triggered = false; } } } catch (Exception ex) { LogMessage("Windy: ERROR - " + ex.Message); - HttpUploadAlarm.LastMessage = "Windy: " + ex.Message; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = "Windy: " + ex.Message; + ThirdPartyAlarm.Triggered = true; } finally { @@ -2342,20 +2345,20 @@ internal async void UpdateWindGuru(DateTime timestamp) if (response.StatusCode != HttpStatusCode.OK) { LogMessage("WindGuru: ERROR - " + response.StatusCode + ": " + responseBodyAsText); - HttpUploadAlarm.LastMessage = "WindGuru: HTTP response - " + response.StatusCode; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = "WindGuru: HTTP response - " + response.StatusCode; + ThirdPartyAlarm.Triggered = true; } else { - HttpUploadAlarm.Triggered = false; + ThirdPartyAlarm.Triggered = false; } } } catch (Exception ex) { LogMessage("WindGuru: ERROR - " + ex.Message); - HttpUploadAlarm.LastMessage = "WindGuru: " + ex.Message; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = "WindGuru: " + ex.Message; + ThirdPartyAlarm.Triggered = true; } finally { @@ -2394,14 +2397,14 @@ internal async void UpdateAwekas(DateTime timestamp) if (response.StatusCode != HttpStatusCode.OK) { LogMessage($"AWEKAS: ERROR - Response code = {response.StatusCode}, body = {responseBodyAsText}"); - HttpUploadAlarm.LastMessage = $"AWEKAS: HTTP Response code = {response.StatusCode}, body = {responseBodyAsText}"; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = $"AWEKAS: HTTP Response code = {response.StatusCode}, body = {responseBodyAsText}"; + ThirdPartyAlarm.Triggered = true; AWEKAS.Updating = false; return; } else { - HttpUploadAlarm.Triggered = false; + ThirdPartyAlarm.Triggered = false; } AwekasResponse respJson; @@ -2413,8 +2416,8 @@ internal async void UpdateAwekas(DateTime timestamp) { LogMessage("AWEKAS: Exception deserializing response = " + ex.Message); LogMessage($"AWEKAS: ERROR - Response body = {responseBodyAsText}"); - HttpUploadAlarm.LastMessage = "AWEKAS deserializing response: " + ex.Message; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = "AWEKAS deserializing response: " + ex.Message; + ThirdPartyAlarm.Triggered = true; AWEKAS.Updating = false; return; } @@ -2471,8 +2474,8 @@ internal async void UpdateAwekas(DateTime timestamp) else { LogMessage("AWEKAS: Unknown error"); - HttpUploadAlarm.LastMessage = "AWEKAS: Unknown error"; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = "AWEKAS: Unknown error"; + ThirdPartyAlarm.Triggered = true; } } @@ -2506,8 +2509,8 @@ internal async void UpdateAwekas(DateTime timestamp) catch (Exception ex) { LogMessage("AWEKAS: Exception = " + ex.Message); - HttpUploadAlarm.LastMessage = "AWEKAS: " + ex.Message; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = "AWEKAS: " + ex.Message; + ThirdPartyAlarm.Triggered = true; } finally { @@ -2544,32 +2547,32 @@ internal async void UpdateWCloud(DateTime timestamp) { case 200: msg = "Success"; - HttpUploadAlarm.Triggered = false; + ThirdPartyAlarm.Triggered = false; break; case 400: msg = "Bad request"; - HttpUploadAlarm.LastMessage = "WeatherCloud: " + msg; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = "WeatherCloud: " + msg; + ThirdPartyAlarm.Triggered = true; break; case 401: msg = "Incorrect WID or Key"; - HttpUploadAlarm.LastMessage = "WeatherCloud: " + msg; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = "WeatherCloud: " + msg; + ThirdPartyAlarm.Triggered = true; break; case 429: msg = "Too many requests"; - HttpUploadAlarm.LastMessage = "WeatherCloud: " + msg; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = "WeatherCloud: " + msg; + ThirdPartyAlarm.Triggered = true; break; case 500: msg = "Server error"; - HttpUploadAlarm.LastMessage = "WeatherCloud: " + msg; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = "WeatherCloud: " + msg; + ThirdPartyAlarm.Triggered = true; break; default: msg = "Unknown error"; - HttpUploadAlarm.LastMessage = "WeatherCloud: " + msg; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = "WeatherCloud: " + msg; + ThirdPartyAlarm.Triggered = true; break; } if ((int) response.StatusCode == 200) @@ -2581,8 +2584,8 @@ internal async void UpdateWCloud(DateTime timestamp) catch (Exception ex) { LogMessage("WeatherCloud: ERROR - " + ex.Message); - HttpUploadAlarm.LastMessage = "WeatherCloud: " + ex.Message; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = "WeatherCloud: " + ex.Message; + ThirdPartyAlarm.Triggered = true; } finally { @@ -2619,20 +2622,20 @@ internal async void UpdateOpenWeatherMap(DateTime timestamp) if (response.StatusCode != HttpStatusCode.NoContent) { LogMessage($"OpenWeatherMap: ERROR - Response code = {response.StatusCode}, Response data = {responseBodyAsText}"); - HttpUploadAlarm.LastMessage = $"OpenWeatherMap: HTTP response - {response.StatusCode}, Response data = {responseBodyAsText}"; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = $"OpenWeatherMap: HTTP response - {response.StatusCode}, Response data = {responseBodyAsText}"; + ThirdPartyAlarm.Triggered = true; } else { - HttpUploadAlarm.Triggered = false; + ThirdPartyAlarm.Triggered = false; } } } catch (Exception ex) { LogMessage("OpenWeatherMap: ERROR - " + ex.Message); - HttpUploadAlarm.LastMessage = "OpenWeatherMap: " + ex.Message; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = "OpenWeatherMap: " + ex.Message; + ThirdPartyAlarm.Triggered = true; } finally { @@ -2884,6 +2887,8 @@ private async void RealtimeFTPReconnect() return; RealtimeFtpReconnecting = true; + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = "Realtime re-connecting"; await Task.Run(() => { bool connected; @@ -4544,6 +4549,8 @@ private void ReadIniFile() WMR928TempChannel = ini.GetValue("Station", "WMR928TempChannel", 0); WMR200TempChannel = ini.GetValue("Station", "WMR200TempChannel", 1); + WxnowComment = ini.GetValue("Station", "WxnowComment.txt", string.Empty); + // WeatherLink Live device settings WllApiKey = ini.GetValue("WLL", "WLv2ApiKey", ""); WllApiSecret = ini.GetValue("WLL", "WLv2ApiSecret", ""); @@ -5350,16 +5357,16 @@ private void ReadIniFile() UpgradeAlarm.Action = ini.GetValue("Alarms", "UpgradeAlarmAction", ""); UpgradeAlarm.ActionParams = ini.GetValue("Alarms", "UpgradeAlarmActionParams", ""); - HttpUploadAlarm.Enabled = ini.GetValue("Alarms", "HttpUploadAlarmSet", false); - HttpUploadAlarm.Sound = ini.GetValue("Alarms", "HttpUploadAlarmSound", false); - HttpUploadAlarm.SoundFile = ini.GetValue("Alarms", "HttpUploadAlarmSoundFile", DefaultSoundFile); - HttpUploadAlarm.Notify = ini.GetValue("Alarms", "HttpUploadAlarmNotify", false); - HttpUploadAlarm.Email = ini.GetValue("Alarms", "HttpUploadAlarmEmail", false); - HttpUploadAlarm.Latch = ini.GetValue("Alarms", "HttpUploadAlarmLatch", false); - HttpUploadAlarm.LatchHours = ini.GetValue("Alarms", "HttpUploadAlarmLatchHours", 24); - HttpUploadAlarm.TriggerThreshold = ini.GetValue("Alarms", "HttpUploadAlarmTriggerCount", 1); - HttpUploadAlarm.Action = ini.GetValue("Alarms", "HttpUploadAlarmAction", ""); - HttpUploadAlarm.ActionParams = ini.GetValue("Alarms", "HttpUploadAlarmActionParams", ""); + ThirdPartyAlarm.Enabled = ini.GetValue("Alarms", "HttpUploadAlarmSet", false); + ThirdPartyAlarm.Sound = ini.GetValue("Alarms", "HttpUploadAlarmSound", false); + ThirdPartyAlarm.SoundFile = ini.GetValue("Alarms", "HttpUploadAlarmSoundFile", DefaultSoundFile); + ThirdPartyAlarm.Notify = ini.GetValue("Alarms", "HttpUploadAlarmNotify", false); + ThirdPartyAlarm.Email = ini.GetValue("Alarms", "HttpUploadAlarmEmail", false); + ThirdPartyAlarm.Latch = ini.GetValue("Alarms", "HttpUploadAlarmLatch", false); + ThirdPartyAlarm.LatchHours = ini.GetValue("Alarms", "HttpUploadAlarmLatchHours", 24); + ThirdPartyAlarm.TriggerThreshold = ini.GetValue("Alarms", "HttpUploadAlarmTriggerCount", 1); + ThirdPartyAlarm.Action = ini.GetValue("Alarms", "HttpUploadAlarmAction", ""); + ThirdPartyAlarm.ActionParams = ini.GetValue("Alarms", "HttpUploadAlarmActionParams", ""); MySqlUploadAlarm.Enabled = ini.GetValue("Alarms", "MySqlUploadAlarmSet", false); MySqlUploadAlarm.Sound = ini.GetValue("Alarms", "MySqlUploadAlarmSound", false); @@ -5382,6 +5389,16 @@ private void ReadIniFile() NewRecordAlarm.Action = ini.GetValue("Alarms", "NewRecordAlarmAction", ""); NewRecordAlarm.ActionParams = ini.GetValue("Alarms", "NewRecordAlarmActionParams", ""); + FtpAlarm.Enabled = ini.GetValue("Alarms", "FtpAlarmSet", false); + FtpAlarm.Sound = ini.GetValue("Alarms", "FtpAlarmSound", false); + FtpAlarm.SoundFile = ini.GetValue("Alarms", "FtpAlarmSoundFile", DefaultSoundFile); + FtpAlarm.Notify = ini.GetValue("Alarms", "FtpAlarmNotify", false); + FtpAlarm.Email = ini.GetValue("Alarms", "FtpAlarmEmail", false); + FtpAlarm.Latch = ini.GetValue("Alarms", "FtpAlarmLatch", false); + FtpAlarm.LatchHours = ini.GetValue("Alarms", "FtpAlarmLatchHours", 24); + FtpAlarm.Action = ini.GetValue("Alarms", "FtpAlarmAction", ""); + FtpAlarm.ActionParams = ini.GetValue("Alarms", "FtpAlarmActionParams", ""); + AlarmFromEmail = ini.GetValue("Alarms", "FromEmail", ""); AlarmDestEmail = ini.GetValue("Alarms", "DestEmail", "").Split(';'); AlarmEmailHtml = ini.GetValue("Alarms", "UseHTML", false); @@ -6002,6 +6019,7 @@ internal void WriteIniFile() ini.SetValue("Station", "WeatherFlowToken", WeatherFlowOptions.WFToken); ini.SetValue("Station", "WeatherFlowDaysHist", WeatherFlowOptions.WFDaysHist); + ini.SetValue("Station", "WxnowComment.txt", WxnowComment); // WeatherLink Live device settings ini.SetValue("WLL", "AutoUpdateIpAddress", WLLAutoUpdateIpAddress); @@ -6521,16 +6539,16 @@ internal void WriteIniFile() ini.SetValue("Alarms", "UpgradeAlarmAction", UpgradeAlarm.Action); ini.SetValue("Alarms", "UpgradeAlarmActionParams", UpgradeAlarm.ActionParams); - ini.SetValue("Alarms", "HttpUploadAlarmSet", HttpUploadAlarm.Enabled); - ini.SetValue("Alarms", "HttpUploadAlarmSound", HttpUploadAlarm.Sound); - ini.SetValue("Alarms", "HttpUploadAlarmSoundFile", HttpUploadAlarm.SoundFile); - ini.SetValue("Alarms", "HttpUploadAlarmNotify", HttpUploadAlarm.Notify); - ini.SetValue("Alarms", "HttpUploadAlarmEmail", HttpUploadAlarm.Email); - ini.SetValue("Alarms", "HttpUploadAlarmLatch", HttpUploadAlarm.Latch); - ini.SetValue("Alarms", "HttpUploadAlarmLatchHours", HttpUploadAlarm.LatchHours); - ini.SetValue("Alarms", "HttpUploadAlarmTriggerCount", HttpUploadAlarm.TriggerThreshold); - ini.SetValue("Alarms", "HttpUploadAlarmAction", HttpUploadAlarm.Action); - ini.SetValue("Alarms", "HttpUploadAlarmActionParams", HttpUploadAlarm.ActionParams); + ini.SetValue("Alarms", "HttpUploadAlarmSet", ThirdPartyAlarm.Enabled); + ini.SetValue("Alarms", "HttpUploadAlarmSound", ThirdPartyAlarm.Sound); + ini.SetValue("Alarms", "HttpUploadAlarmSoundFile", ThirdPartyAlarm.SoundFile); + ini.SetValue("Alarms", "HttpUploadAlarmNotify", ThirdPartyAlarm.Notify); + ini.SetValue("Alarms", "HttpUploadAlarmEmail", ThirdPartyAlarm.Email); + ini.SetValue("Alarms", "HttpUploadAlarmLatch", ThirdPartyAlarm.Latch); + ini.SetValue("Alarms", "HttpUploadAlarmLatchHours", ThirdPartyAlarm.LatchHours); + ini.SetValue("Alarms", "HttpUploadAlarmTriggerCount", ThirdPartyAlarm.TriggerThreshold); + ini.SetValue("Alarms", "HttpUploadAlarmAction", ThirdPartyAlarm.Action); + ini.SetValue("Alarms", "HttpUploadAlarmActionParams", ThirdPartyAlarm.ActionParams); ini.SetValue("Alarms", "MySqlUploadAlarmSet", MySqlUploadAlarm.Enabled); ini.SetValue("Alarms", "MySqlUploadAlarmSound", MySqlUploadAlarm.Sound); @@ -6553,6 +6571,16 @@ internal void WriteIniFile() ini.SetValue("Alarms", "NewRecordAlarmAction", NewRecordAlarm.Action); ini.SetValue("Alarms", "NewRecordAlarmActionParams", NewRecordAlarm.ActionParams); + ini.SetValue("Alarms", "FtpAlarmSet", FtpAlarm.Enabled); + ini.SetValue("Alarms", "FtpAlarmSound", FtpAlarm.Sound); + ini.SetValue("Alarms", "FtpAlarmSoundFile", FtpAlarm.SoundFile); + ini.SetValue("Alarms", "FtpAlarmNotify", FtpAlarm.Notify); + ini.SetValue("Alarms", "FtpAlarmEmail", FtpAlarm.Email); + ini.SetValue("Alarms", "FtpAlarmLatch", FtpAlarm.Latch); + ini.SetValue("Alarms", "FtpAlarmLatchHours", FtpAlarm.LatchHours); + ini.SetValue("Alarms", "FtpAlarmAction", FtpAlarm.Action); + ini.SetValue("Alarms", "FtpAlarmActionParams", FtpAlarm.ActionParams); + ini.SetValue("Alarms", "FromEmail", AlarmFromEmail); ini.SetValue("Alarms", "DestEmail", AlarmDestEmail.Join(";")); ini.SetValue("Alarms", "UseHTML", AlarmEmailHtml); @@ -7120,10 +7148,11 @@ private void ReadStringsFile() BatteryLowAlarm.EmailMsg = ini.GetValue("AlarmEmails", "batteryLow", "A low battery condition has been detected."); SpikeAlarm.EmailMsg = ini.GetValue("AlarmEmails", "dataSpike", "A data spike from your weather station has been suppressed."); UpgradeAlarm.EmailMsg = ini.GetValue("AlarmEmails", "upgrade", "An upgrade to Cumulus MX is now available."); - HttpUploadAlarm.EmailMsg = ini.GetValue("AlarmEmails", "httpStopped", "HTTP uploads are failing."); + ThirdPartyAlarm.EmailMsg = ini.GetValue("AlarmEmails", "httpStopped", "Third party HTTP uploads are failing."); MySqlUploadAlarm.EmailMsg = ini.GetValue("AlarmEmails", "mySqlStopped", "MySQL uploads are failing."); IsRainingAlarm.EmailMsg = ini.GetValue("AlarmEmails", "isRaining", "It has started to rain."); NewRecordAlarm.EmailMsg = ini.GetValue("AlarmEmails", "newRecord", "A new all-time record has been set."); + FtpAlarm.EmailMsg = ini.GetValue("AlarmEmails", "ftpStopped", "FTP uploads have stopped."); if (!File.Exists("strings.ini")) { @@ -7284,7 +7313,7 @@ public void WriteStringsFile() ini.SetValue("AlarmEmails", "batteryLow", BatteryLowAlarm.EmailMsg); ini.SetValue("AlarmEmails", "dataSpike", SpikeAlarm.EmailMsg); ini.SetValue("AlarmEmails", "upgrade", UpgradeAlarm.EmailMsg); - ini.SetValue("AlarmEmails", "httpStopped", HttpUploadAlarm.EmailMsg); + ini.SetValue("AlarmEmails", "httpStopped", ThirdPartyAlarm.EmailMsg); ini.SetValue("AlarmEmails", "mySqlStopped", MySqlUploadAlarm.EmailMsg); ini.SetValue("AlarmEmails", "isRaining", IsRainingAlarm.EmailMsg); @@ -8901,7 +8930,6 @@ public int GetHourInc(DateTime timestamp) // Locale is currently on Daylight time return -10; } - else { // Locale is currently on Standard time or unknown @@ -9817,6 +9845,9 @@ public async Task DoIntervalUpload() { LogFtpMessage($"SFTP[Int]: Error connecting SFTP - {ex.Message}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = "Error connecting SFTP - " + ex.Message; + if ((uint) ex.HResult == 0x80004005) // Could not resolve host { // Disable the DNS cache for the next query @@ -9849,6 +9880,8 @@ public async Task DoIntervalUpload() catch (Exception e) { LogFtpMessage($"SFTP[Int]: Error uploading file - {e.Message}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = "Error uploading NOAA report file - " + e.Message; } NOAAconf.NeedFtp = false; } @@ -9896,11 +9929,15 @@ public async Task DoIntervalUpload() { LogFtpMessage($"SFTP[Int]: Error uploading Extra web file #{i} [{uploadfile}]"); LogFtpMessage($"SFTP[Int]: Error = {e.Message}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error uploading Extra web file #{i} [{uploadfile}"; } } else { LogFtpMessage($"SFTP[Int]: Extra web file #{i} [{uploadfile}] not found!"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error Extra web file #{i} [{uploadfile} not found"; } } } @@ -9940,6 +9977,8 @@ public async Task DoIntervalUpload() { LogFtpMessage($"SFTP[Int]: Error uploading standard data file [{StdWebFiles[i].RemoteFileName}]"); LogFtpMessage($"SFTP[Int]: Error = {e}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error uploading standard web file {StdWebFiles[i].RemoteFileName} - {e.Message}"; } } } @@ -9972,6 +10011,8 @@ public async Task DoIntervalUpload() { LogFtpMessage($"SFTP[Int]: Error uploading graph data file [{uploadfile}]"); LogFtpMessage($"SFTP[Int]: Error = {e}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error uploading graph data file [{uploadfile}] - {e.Message}"; } } } @@ -9999,6 +10040,8 @@ public async Task DoIntervalUpload() { LogFtpMessage($"SFTP[Int]: Error uploading daily graph data file [{uploadfile}]"); LogFtpMessage($"SFTP[Int]: Error = {e}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error uploading daily graph data file [{uploadfile}] - {e.Message}"; } } } @@ -10016,6 +10059,8 @@ public async Task DoIntervalUpload() catch (Exception e) { LogMessage($"SFTP[Int]: Error uploading moon image - {e.Message}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error uploading moon image - {e.Message}"; } } } @@ -10094,6 +10139,9 @@ public async Task DoIntervalUpload() { LogFtpMessage("FTP[Int]: Error connecting ftp - " + ex.Message); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = "Error connecting ftp - " + ex.Message; + if (ex.InnerException != null) { ex = Utils.GetOriginalException(ex); @@ -10132,6 +10180,8 @@ public async Task DoIntervalUpload() catch (Exception e) { LogFtpMessage($"FTP[Int]: Error uploading NOAA files: {e.Message}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = "Error connecting ftp - " + e.Message; } NOAAconf.NeedFtp = false; } @@ -10180,6 +10230,8 @@ public async Task DoIntervalUpload() catch (Exception e) { LogFtpMessage($"FTP[Int]: Error uploading file {uploadfile}: {e.Message}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error uploading extra file {uploadfile} - {e.Message}"; } } else @@ -10225,6 +10277,8 @@ public async Task DoIntervalUpload() catch (Exception e) { LogFtpMessage($"FTP[Int]: Error uploading file {StdWebFiles[i].RemoteFileName}: {e}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error uploading file {StdWebFiles[i].RemoteFileName} - {e.Message}"; } } } @@ -10256,6 +10310,8 @@ public async Task DoIntervalUpload() { LogFtpMessage($"FTP[Int]: Error uploading graph data file [{GraphDataFiles[i].RemoteFileName}]"); LogFtpMessage($"FTP[Int]: Error = {e}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error uploading file {GraphDataFiles[i].RemoteFileName} - {e.Message}"; } } } @@ -10284,6 +10340,8 @@ public async Task DoIntervalUpload() { LogFtpMessage($"FTP[Int]: Error uploading daily graph data file [{GraphDataEodFiles[i].RemoteFileName}]"); LogFtpMessage($"FTP[Int]: Error = {e}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error uploading file {GraphDataEodFiles[i].RemoteFileName} - {e.Message}"; } } } @@ -10301,6 +10359,8 @@ public async Task DoIntervalUpload() catch (Exception e) { LogMessage($"FTP[Int]: Error uploading moon image - {e.Message}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error uploading moon image - {e.Message}"; } } } @@ -10358,6 +10418,8 @@ public async Task DoIntervalUpload() catch (Exception ex) { LogExceptionMessage(ex, $"PHP[Int]: Error uploading NOAA files"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error uploading NOAA files - {ex.Message}"; } finally { @@ -10415,6 +10477,8 @@ public async Task DoIntervalUpload() catch (Exception ex) { LogExceptionMessage(ex, $"PHP[Int]: Error uploading NOAA Year file"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error uploading NOAA files - {ex.Message}"; } finally { @@ -10503,6 +10567,8 @@ public async Task DoIntervalUpload() catch (Exception ex) when (!(ex is TaskCanceledException)) { LogExceptionMessage(ex, $"PHP[Int]: Error uploading file {uploadfile} to: {remotefile}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error uploading file {uploadfile} to: {remotefile} - {ex.Message}"; } finally { @@ -10591,6 +10657,8 @@ public async Task DoIntervalUpload() catch (Exception ex) { LogExceptionMessage(ex, $"PHP[Int]: Error uploading file {item.RemoteFileName}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error uploading file {item.RemoteFileName} - {ex.Message}"; } finally { @@ -10680,6 +10748,8 @@ public async Task DoIntervalUpload() catch (Exception ex) { LogExceptionMessage(ex, $"PHP[Int]: Error uploading graph data file [{item.RemoteFileName}]"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error uploading graph data file [{item.RemoteFileName}] - {ex.Message}"; } finally { @@ -10756,6 +10826,8 @@ public async Task DoIntervalUpload() catch (Exception ex) { LogExceptionMessage(ex, $"PHP[Int]: Error uploading daily graph data file [{item.RemoteFileName}]"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error uploading daily graph data file [{item.RemoteFileName}] - {ex.Message}"; } finally { @@ -10820,6 +10892,8 @@ public async Task DoIntervalUpload() catch (Exception ex) { LogExceptionMessage(ex, "PHP[Int]: Error uploading moon image"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error uploading moon image - {ex.Message}"; } finally { @@ -10855,7 +10929,9 @@ public async Task DoIntervalUpload() } catch(Exception ex) { - LogExceptionMessage(ex, "PHP[Int]: Eror waiting on upload tasks"); + LogExceptionMessage(ex, "PHP[Int]: Error waiting on upload tasks"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = "Error waiting on upload tasks"; } } //LogDebugMessage($"PHP[Int]: EOD Graph files upload complete, {tasklist.Count()} files processed"); @@ -10888,6 +10964,8 @@ private bool UploadFile(FtpClient conn, string localfile, string remotefile, int if (!File.Exists(localfile)) { LogMessage($"FTP[{cycleStr}]: Error! Local file not found, aborting upload: {localfile}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error! Local file not found, aborting upload: {localfile}"; return true; } @@ -10899,6 +10977,9 @@ private bool UploadFile(FtpClient conn, string localfile, string remotefile, int catch (Exception ex) { LogFtpMessage($"FTP[{cycleStr}]: Error reading {localfile} - {ex.Message}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error reading {localfile} - {ex.Message}"; + if (ex.InnerException != null) { LogFtpMessage($"FTP[{cycleStr}]: Inner Exception: {ex.GetBaseException().Message}"); @@ -10918,6 +10999,9 @@ private bool UploadStream(FtpClient conn, string remotefile, Stream dataStream, if (dataStream.Length == 0) { LogMessage($"FTP[{cycleStr}]: The data is empty - skipping upload of {remotefile}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"The data is empty - skipping upload of {remotefile}"; + return true; } @@ -10955,6 +11039,10 @@ private bool UploadStream(FtpClient conn, string remotefile, Stream dataStream, catch (Exception ex) { LogFtpMessage($"FTP[{cycleStr}]: Error deleting {remotefile} : {ex.Message}"); + + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error deleting {remotefile} : {ex.Message}"; + if (ex.InnerException != null) { ex = Utils.GetOriginalException(ex); @@ -10986,6 +11074,10 @@ private bool UploadStream(FtpClient conn, string remotefile, Stream dataStream, catch (Exception ex) { LogFtpMessage($"FTP[{cycleStr}]: Error renaming {remotefiletmp} to {remotefile} : {ex.Message}"); + + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error renaming {remotefiletmp} to {remotefile} : {ex.Message}"; + if (ex.InnerException != null) { ex = Utils.GetOriginalException(ex); @@ -10999,6 +11091,10 @@ private bool UploadStream(FtpClient conn, string remotefile, Stream dataStream, catch (Exception ex) { LogFtpMessage($"FTP[{cycleStr}]: Error uploading {remotefile} : {ex.Message}"); + + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error uploading {remotefile} : {ex.Message}"; + if (ex.InnerException != null) { LogFtpMessage($"FTP[{cycleStr}]: Inner Exception: {ex.GetBaseException().Message}"); @@ -11027,6 +11123,9 @@ private bool UploadFile(SftpClient conn, string localfile, string remotefile, in if (!File.Exists(localfile)) { LogMessage($"SFTP[{cycleStr}]: Error! Local file not found, aborting upload: {localfile}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error! Local file not found, aborting upload: {localfile}"; + return true; } @@ -11035,14 +11134,22 @@ private bool UploadFile(SftpClient conn, string localfile, string remotefile, in if (conn == null || !conn.IsConnected) { LogFtpMessage($"SFTP[{cycleStr}]: The SFTP object is null or not connected - skipping upload of {localfile}"); - RealtimeFTPReconnect(); + + if (cycle >= 0) + RealtimeFTPReconnect(); + return false; } } catch (ObjectDisposedException) { LogFtpMessage($"SFTP[{cycleStr}]: The SFTP object is disposed - skipping upload of {localfile}"); - RealtimeFTPReconnect(); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"The SFTP object is disposed - skipping upload of {localfile}"; + + if (cycle >=0) + RealtimeFTPReconnect(); + return false; } @@ -11056,6 +11163,10 @@ private bool UploadFile(SftpClient conn, string localfile, string remotefile, in catch (Exception ex) { LogFtpMessage($"SFTP[{cycleStr}]: Error reading {localfile} - {ex.Message}"); + + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error reading {localfile} - {ex.Message}"; + if (ex.InnerException != null) { ex = Utils.GetOriginalException(ex); @@ -11074,6 +11185,8 @@ private bool UploadStream(SftpClient conn, string remotefile, Stream dataStream, if (dataStream.Length == 0) { LogFtpMessage($"SFTP[{cycleStr}]: The data is empty - skipping upload of {remotefile}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"The data is empty - skipping upload of {remotefile}"; return false; } @@ -11082,14 +11195,25 @@ private bool UploadStream(SftpClient conn, string remotefile, Stream dataStream, if (conn == null || !conn.IsConnected) { LogFtpMessage($"SFTP[{cycleStr}]: The SFTP object is null or not connected - skipping upload of {remotefile}"); - RealtimeFTPReconnect(); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"The SFTP object is null or not connected - skipping upload of {remotefile}"; + + if (cycle >= 0) + RealtimeFTPReconnect(); + return false; } } catch (ObjectDisposedException) { LogFtpMessage($"SFTP[{cycleStr}]: The SFTP object is disposed - skipping upload of {remotefile}"); - RealtimeFTPReconnect(); + + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"The SFTP object is disposed - skipping upload of {remotefile}"; + + if (cycle >= 0) + RealtimeFTPReconnect(); + return false; } @@ -11109,12 +11233,17 @@ private bool UploadStream(SftpClient conn, string remotefile, Stream dataStream, catch (ObjectDisposedException) { LogFtpMessage($"SFTP[{cycleStr}]: The SFTP object is disposed"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"The SFTP object is disposed - skipping upload of {remotefile}"; return false; } catch (Exception ex) { LogFtpMessage($"SFTP[{cycleStr}]: Error uploading {remotefilename} : {ex.Message}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error uploading {remotefilename} : {ex.Message}"; + if (ex.Message.Contains("Permission denied")) // Non-fatal return true; @@ -11141,11 +11270,17 @@ private bool UploadStream(SftpClient conn, string remotefile, Stream dataStream, catch (ObjectDisposedException) { LogFtpMessage($"SFTP[{cycleStr}]: The SFTP object is disposed"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"The SFTP object is disposed during renaming of {remotefile}"; return false; } catch (Exception ex) { LogFtpMessage($"SFTP[{cycleStr}]: Error renaming {remotefilename} to {remotefile} : {ex.Message}"); + + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error renaming {remotefilename} to {remotefile} : {ex.Message}"; + if (ex.InnerException != null) { ex = Utils.GetOriginalException(ex); @@ -11160,11 +11295,17 @@ private bool UploadStream(SftpClient conn, string remotefile, Stream dataStream, catch (ObjectDisposedException) { LogFtpMessage($"SFTP[{cycleStr}]: The SFTP object is disposed"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = "The SFTP object is disposed"; return false; } catch (Exception ex) { LogFtpMessage($"SFTP[{cycleStr}]: Error uploading {remotefile} - {ex.Message}"); + + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error uploading {remotefile} - {ex.Message}"; + if (ex.InnerException != null) { ex = Utils.GetOriginalException(ex); @@ -11188,6 +11329,10 @@ private async Task UploadFile(HttpClient httpclient, string localfile, str if (!File.Exists(localfile)) { LogMessage($"PHP[{cycleStr}]: Error! Local file not found, aborting upload: {localfile}"); + + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $"Error! Local file not found, aborting upload: {localfile}"; + return false; } @@ -11209,6 +11354,10 @@ private async Task UploadFile(HttpClient httpclient, string localfile, str catch (Exception ex) { LogDebugMessage($"PHP[{cycleStr}]: Error - {ex.Message}"); + + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $" Error - {ex.Message}"; + return false; } } @@ -11220,6 +11369,8 @@ private async Task UploadString(HttpClient httpclient, bool incremental, s if (string.IsNullOrEmpty(data)) { LogMessage($"PHP[{cycleStr}]: Uploading to {remotefile}. Error: The data string is empty, ignoring this upload"); + + return false; } LogDebugMessage($"PHP[{cycleStr}]: Uploading to {remotefile}"); @@ -11320,6 +11471,10 @@ private async Task UploadString(HttpClient httpclient, bool incremental, s catch (System.Net.Http.HttpRequestException ex) { LogExceptionMessage(ex, $"PHP[{cycleStr}]: Error uploading to {remotefile}"); + + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $" Error uploading to {remotefile} - {ex.Message}"; + retry++; if (retry < 2) { @@ -11329,6 +11484,8 @@ private async Task UploadString(HttpClient httpclient, bool incremental, s catch (Exception ex) { LogExceptionMessage(ex, $"PHP[{cycleStr}]: Error uploading to {remotefile}"); + FtpAlarm.Triggered = true; + FtpAlarm.LastMessage = $" Error uploading to {remotefile} - {ex.Message}"; retry = 99; } finally @@ -12585,21 +12742,21 @@ public async void UpdatePWSweather(DateTime timestamp) if (response.StatusCode != HttpStatusCode.OK) { LogMessage($"PWS Response: ERROR - Response code = {response.StatusCode}, Body = {responseBodyAsText}"); - HttpUploadAlarm.LastMessage = $"PWS: HTTP Response code = {response.StatusCode}, Body = {responseBodyAsText}"; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = $"PWS: HTTP Response code = {response.StatusCode}, Body = {responseBodyAsText}"; + ThirdPartyAlarm.Triggered = true; } else { LogDebugMessage("PWS Response: " + response.StatusCode + ": " + responseBodyAsText); - HttpUploadAlarm.Triggered = false; + ThirdPartyAlarm.Triggered = false; } } } catch (Exception ex) { LogMessage("PWS update: " + ex.Message); - HttpUploadAlarm.LastMessage = "PWS: " + ex.Message; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = "PWS: " + ex.Message; + ThirdPartyAlarm.Triggered = true; } finally { @@ -12630,21 +12787,21 @@ public async void UpdateWOW(DateTime timestamp) if (response.StatusCode != HttpStatusCode.OK) { LogMessage($"WOW Response: ERROR - Response code = {response.StatusCode}, body = {responseBodyAsText}"); - HttpUploadAlarm.LastMessage = $"WOW: HTTP response - Response code = {response.StatusCode}, body = {responseBodyAsText}"; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = $"WOW: HTTP response - Response code = {response.StatusCode}, body = {responseBodyAsText}"; + ThirdPartyAlarm.Triggered = true; } else { LogDebugMessage("WOW Response: " + response.StatusCode + ": " + responseBodyAsText); - HttpUploadAlarm.Triggered = false; + ThirdPartyAlarm.Triggered = false; } } } catch (Exception ex) { LogMessage("WOW update: " + ex.Message); - HttpUploadAlarm.LastMessage = "WOW: " + ex.Message; - HttpUploadAlarm.Triggered = true; + ThirdPartyAlarm.LastMessage = "WOW: " + ex.Message; + ThirdPartyAlarm.Triggered = true; } finally { diff --git a/CumulusMX/DataEditor.cs b/CumulusMX/DataEditor.cs index c63a59f4..6a009dc6 100644 --- a/CumulusMX/DataEditor.cs +++ b/CumulusMX/DataEditor.cs @@ -662,7 +662,7 @@ internal string GetRecordsLogFile(string recordType) const string monthFormat = "MMM yyyy"; var json = new StringBuilder("{", 2048); - DateTime datefrom; + DateTime filedate, datefrom; switch (recordType) { @@ -671,11 +671,13 @@ internal string GetRecordsLogFile(string recordType) break; case "thisyear": var now = DateTime.Now; - datefrom = new DateTime(now.Year, 1, 1); + filedate = new DateTime(now.Year, 1, 1).Date; + datefrom = filedate.AddDays(-1); break; case "thismonth": now = DateTime.Now; - datefrom = new DateTime(now.Year, now.Month, 1).Date; + filedate = new DateTime(now.Year, now.Month, 1).Date; + datefrom = filedate.AddDays(-1); break; default: datefrom = cumulus.RecordsBeganDateTime; @@ -684,7 +686,7 @@ internal string GetRecordsLogFile(string recordType) var dateto = DateTime.Now.Date; // we have to go back 24 hour to calculate rain in 24h value - var filedate = datefrom.AddDays(-1); + filedate = datefrom.AddDays(-1); var logFile = cumulus.GetLogFileName(filedate); var started = false; diff --git a/CumulusMX/InternetSettings.cs b/CumulusMX/InternetSettings.cs index 31b8ba87..9f8ebc2a 100644 --- a/CumulusMX/InternetSettings.cs +++ b/CumulusMX/InternetSettings.cs @@ -162,6 +162,8 @@ public string UpdateConfig(IHttpContext context) cumulus.StdWebFiles[i].Copy = settings.websettings.interval.stdfiles.files[i].copy; } + cumulus.WxnowComment = settings.websettings.interval.stdfiles.wxnowcomment; + for (var i = 0; i < cumulus.GraphDataFiles.Length; i++) { cumulus.GraphDataFiles[i].Create = settings.websettings.interval.graphfiles.files[i].create; @@ -419,7 +421,8 @@ public string GetAlpacaFormData() var websettingsintervalstd = new JsonInternetSettingsWebSettingsIntervalFiles() { - files = new JsonInternetSettingsFileSettings[cumulus.StdWebFiles.Length] + files = new JsonInternetSettingsFileSettings[cumulus.StdWebFiles.Length], + wxnowcomment = cumulus.WxnowComment }; var websettingsintervalgraph = new JsonInternetSettingsWebSettingsIntervalFiles() @@ -763,6 +766,7 @@ public class JsonInternetSettingsWebSettingsInterval public class JsonInternetSettingsWebSettingsIntervalFiles { public JsonInternetSettingsFileSettings[] files { get; set; } + public string wxnowcomment { get; set; } } diff --git a/CumulusMX/LangSettings.cs b/CumulusMX/LangSettings.cs index cd8f4be7..76ea0e69 100644 --- a/CumulusMX/LangSettings.cs +++ b/CumulusMX/LangSettings.cs @@ -129,9 +129,10 @@ public string GetAlpacaFormData() batteryLow = cumulus.BatteryLowAlarm.EmailMsg, dataSpike = cumulus.SpikeAlarm.EmailMsg, upgrade = cumulus.UpgradeAlarm.EmailMsg, - httpStopped = cumulus.HttpUploadAlarm.EmailMsg, + httpStopped = cumulus.ThirdPartyAlarm.EmailMsg, mySqlStopped = cumulus.MySqlUploadAlarm.EmailMsg, - newRecord = cumulus.NewRecordAlarm.EmailMsg + newRecord = cumulus.NewRecordAlarm.EmailMsg, + ftpStopped =cumulus.FtpAlarm.EmailMsg }; var settings = new Settings() @@ -377,9 +378,10 @@ public string UpdateConfig(IHttpContext context) cumulus.BatteryLowAlarm.EmailMsg = settings.alarms.batteryLow.Trim(); cumulus.SpikeAlarm.EmailMsg = settings.alarms.dataSpike.Trim(); cumulus.UpgradeAlarm.EmailMsg = settings.alarms.upgrade.Trim(); - cumulus.HttpUploadAlarm.EmailMsg = settings.alarms.httpStopped.Trim(); + cumulus.ThirdPartyAlarm.EmailMsg = settings.alarms.httpStopped.Trim(); cumulus.MySqlUploadAlarm.EmailMsg = settings.alarms.mySqlStopped.Trim(); cumulus.NewRecordAlarm.EmailMsg = settings.alarms.newRecord.Trim(); + cumulus.FtpAlarm.EmailMsg = settings.alarms.ftpStopped.Trim(); } catch (Exception ex) { @@ -508,6 +510,7 @@ private class AlarmEmails public string httpStopped { get; set; } public string mySqlStopped { get; set; } public string newRecord { get; set; } + public string ftpStopped { get; set; } } private class Settings diff --git a/CumulusMX/WeatherStation.cs b/CumulusMX/WeatherStation.cs index f5daf2b9..84b8e566 100644 --- a/CumulusMX/WeatherStation.cs +++ b/CumulusMX/WeatherStation.cs @@ -1602,7 +1602,7 @@ private void ClearAlarms() cumulus.SensorAlarm.ClearAlarm(); cumulus.SpikeAlarm.ClearAlarm(); cumulus.UpgradeAlarm.ClearAlarm(); - cumulus.HttpUploadAlarm.ClearAlarm(); + cumulus.ThirdPartyAlarm.ClearAlarm(); cumulus.MySqlUploadAlarm.ClearAlarm(); cumulus.HighWindAlarm.ClearAlarm(); cumulus.HighGustAlarm.ClearAlarm(); @@ -1615,6 +1615,7 @@ private void ClearAlarms() cumulus.LowTempAlarm.ClearAlarm(); cumulus.TempChangeAlarm.ClearAlarm(); cumulus.PressChangeAlarm.ClearAlarm(); + cumulus.FtpAlarm.ClearAlarm(); } private void MinuteChanged(DateTime now) @@ -3990,7 +3991,7 @@ public void AddRecentDataEntry(DateTime timestamp, double windAverage, double re public void CreateWxnowFile() { // Jun 01 2003 08:07 - // 272/000g006t069r010p030P020h61b10150 + // 272/000g006t069r010p030P020h61b10150CommentString // 272 - wind direction - 272 degrees // 010 - wind speed - 10 mph @@ -4002,6 +4003,7 @@ public void CreateWxnowFile() // P020 - rain since midnight in hundredths of an inch - 0.2 inches // h61 - humidity 61% (00 = 100%) // b10153 - barometric pressure in tenths of a millibar - 1015.3 millibars + // CommentString - free format information text var filename = cumulus.AppDir + cumulus.WxnowFile; @@ -4016,7 +4018,7 @@ public void CreateWxnowFile() public string CreateWxnowFileString() { // Jun 01 2003 08:07 - // 272/000g006t069r010p030P020h61b10150 + // 272/000g006t069r010p030P020h61b10150CommentString // 272 - wind direction - 272 degrees // 010 - wind speed - 10 mph @@ -4028,6 +4030,7 @@ public string CreateWxnowFileString() // P020 - rain since midnight in hundredths of an inch - 0.2 inches // h61 - humidity 61% (00 = 100%) // b10153 - barometric pressure in tenths of a millibar - 1015.3 millibars + // CommentString - free format information text var timestamp = DateTime.Now.ToString(@"MMM dd yyyy HH\:mm"); @@ -4062,7 +4065,14 @@ public string CreateWxnowFileString() data += APRSsolarradStr(SolarRad); } + if (!String.IsNullOrWhiteSpace(cumulus.WxnowComment)) + { + var tokenParser = new TokenParser(cumulus.TokenParserOnToken); + // process the webtags in the content string + tokenParser.InputText = cumulus.WxnowComment; + data += tokenParser.ToStringFromString(); + } return data; } @@ -13909,7 +13919,7 @@ internal string GetCurrentData() cumulus.BeaufortDesc(WindAverage), LastDataReadTimestamp.ToString(cumulus.ProgramOptions.TimeFormatLong), DataStopped, StormRain, stormRainStart, CloudBase, cumulus.CloudBaseInFeet ? "ft" : "m", RainLast24Hour, cumulus.LowTempAlarm.Triggered, cumulus.HighTempAlarm.Triggered, cumulus.TempChangeAlarm.UpTriggered, cumulus.TempChangeAlarm.DownTriggered, cumulus.HighRainTodayAlarm.Triggered, cumulus.HighRainRateAlarm.Triggered, cumulus.LowPressAlarm.Triggered, cumulus.HighPressAlarm.Triggered, cumulus.PressChangeAlarm.UpTriggered, cumulus.PressChangeAlarm.DownTriggered, cumulus.HighGustAlarm.Triggered, cumulus.HighWindAlarm.Triggered, - cumulus.SensorAlarm.Triggered, cumulus.BatteryLowAlarm.Triggered, cumulus.SpikeAlarm.Triggered, cumulus.UpgradeAlarm.Triggered, cumulus.HttpUploadAlarm.Triggered, cumulus.MySqlUploadAlarm.Triggered, cumulus.IsRainingAlarm.Triggered, + cumulus.SensorAlarm.Triggered, cumulus.BatteryLowAlarm.Triggered, cumulus.SpikeAlarm.Triggered, cumulus.UpgradeAlarm.Triggered, cumulus.ThirdPartyAlarm.Triggered, cumulus.MySqlUploadAlarm.Triggered, cumulus.IsRainingAlarm.Triggered, FeelsLike, HiLoToday.HighFeelsLike, HiLoToday.HighFeelsLikeTime.ToString(cumulus.ProgramOptions.TimeFormat), HiLoToday.LowFeelsLike, HiLoToday.LowFeelsLikeTime.ToString(cumulus.ProgramOptions.TimeFormat), HiLoToday.HighHumidex, HiLoToday.HighHumidexTime.ToString(cumulus.ProgramOptions.TimeFormat)); diff --git a/CumulusMX/webtags.cs b/CumulusMX/webtags.cs index 0d0d08e3..7ee54964 100644 --- a/CumulusMX/webtags.cs +++ b/CumulusMX/webtags.cs @@ -4320,9 +4320,9 @@ private string TagMySqlUploadAlarm(Dictionary tagParams) private string TagHttpUploadAlarm(Dictionary tagParams) { - if (cumulus.HttpUploadAlarm.Enabled) + if (cumulus.ThirdPartyAlarm.Enabled) { - return cumulus.HttpUploadAlarm.Triggered ? "1" : "0"; + return cumulus.ThirdPartyAlarm.Triggered ? "1" : "0"; } return "0"; diff --git a/Updates.txt b/Updates.txt index fdbf0f31..931b3475 100644 --- a/Updates.txt +++ b/Updates.txt @@ -12,13 +12,15 @@ New "doNotTriggerOnTags": "timehhmmss" } Which now will only send a new MQTT message when CMX first starts, then only when the "#temp" value changes. +- Adds new alarm for any all-time record being set +- Adds new alarm "Web upload errors" for errors in the FTP/PHP upload processes Changed - Various third party libraries updated to current versions - MailKit, MQTTnet, MySqlConnector, ServiceStack - PHP upload now sends a text/plain content header - Davis WLL and Airlink now use the new simplified access method to weatherlink.com V2 API -- MX now persists the internal recent wind data across restarts +- MX now persists the internal recent wind data across restarts so gust and average speeds are consistent on a quick stop/start of MX Fixed - PWS passwords are now URL encoded From f5359e2472e5f25fdc8f860419482c501bbb8c23 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Sun, 30 Jul 2023 18:29:56 +0100 Subject: [PATCH 22/27] Fluent FTP updated --- CumulusMX/CumulusMX.csproj | 2 +- Updates.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CumulusMX/CumulusMX.csproj b/CumulusMX/CumulusMX.csproj index 846a2c90..4a60c95b 100644 --- a/CumulusMX/CumulusMX.csproj +++ b/CumulusMX/CumulusMX.csproj @@ -233,7 +233,7 @@ 3.5.2 - 47.0.0 + 47.1.0 2.1.0 diff --git a/Updates.txt b/Updates.txt index 931b3475..ef298f73 100644 --- a/Updates.txt +++ b/Updates.txt @@ -14,6 +14,7 @@ New Which now will only send a new MQTT message when CMX first starts, then only when the "#temp" value changes. - Adds new alarm for any all-time record being set - Adds new alarm "Web upload errors" for errors in the FTP/PHP upload processes +- Adds the ability to append free text comments to the wxnow.txt file. You can also include web tags Changed - Various third party libraries updated to current versions From b5b6b584b9079dad310eae3e506284017022076c Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Mon, 31 Jul 2023 13:06:07 +0100 Subject: [PATCH 23/27] Add #RecentRain web tag --- CumulusMX/webtags.cs | 10 ++++++++++ Updates.txt | 1 + 2 files changed, 11 insertions(+) diff --git a/CumulusMX/webtags.cs b/CumulusMX/webtags.cs index 7ee54964..7addc419 100644 --- a/CumulusMX/webtags.cs +++ b/CumulusMX/webtags.cs @@ -5400,6 +5400,15 @@ private string TagRecentPressure(Dictionary tagParams) return CheckRcDp(CheckPressUnit(result.Count == 0 ? station.Pressure : result[0].Pressure, tagParams), tagParams, cumulus.PressDPlaces); } + private string TagRecentRain(Dictionary tagParams) + { + var recentTs = GetRecentTs(tagParams); + + var result = station.RecentDataDb.ExecuteScalar("select (select raincounter from RecentData order by Timestamp Desc limit 1) - raincounter from RecentData where Timestamp >= ? order by Timestamp limit 1", recentTs); + + return CheckRcDp(CheckPressUnit(result.HasValue ? result.Value : station.RainToday, tagParams), tagParams, cumulus.RainDPlaces); + } + private string TagRecentRainToday(Dictionary tagParams) { var recentTs = GetRecentTs(tagParams); @@ -6327,6 +6336,7 @@ public void InitialiseWebtags() { "RecentHumidex", TagRecentHumidex }, { "RecentHumidity", TagRecentHumidity }, { "RecentPressure", TagRecentPressure }, + { "RecentRain", TagRecentRain }, { "RecentRainToday", TagRecentRainToday }, { "RecentSolarRad", TagRecentSolarRad }, { "RecentUV", TagRecentUv }, diff --git a/Updates.txt b/Updates.txt index ef298f73..edfc20b2 100644 --- a/Updates.txt +++ b/Updates.txt @@ -15,6 +15,7 @@ New - Adds new alarm for any all-time record being set - Adds new alarm "Web upload errors" for errors in the FTP/PHP upload processes - Adds the ability to append free text comments to the wxnow.txt file. You can also include web tags +- New web tag for recent rainfall - <#RecentRain> - it takes the same parameters as the other RecentXxxx web tags, and defaults to todays total if the parameters are incorrect or no recent data is available Changed - Various third party libraries updated to current versions From 9025fa3ac185d4b6966a3c00a1b427c2d05a5a3b Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Tue, 1 Aug 2023 18:47:56 +0100 Subject: [PATCH 24/27] Update to #RecentRain web tag to allow for raincounter resetting Adds #EcowittRecption web tag --- CumulusMX/GW1000Station.cs | 4 +- CumulusMX/WeatherStation.cs | 4 + CumulusMX/webtags.cs | 1328 ++++++++++++++++++----------------- Updates.txt | 7 +- 4 files changed, 702 insertions(+), 641 deletions(-) diff --git a/CumulusMX/GW1000Station.cs b/CumulusMX/GW1000Station.cs index 80d5de4f..d134f00a 100644 --- a/CumulusMX/GW1000Station.cs +++ b/CumulusMX/GW1000Station.cs @@ -41,7 +41,6 @@ internal class GW1000Station : WeatherStation private Version fwVersion; private string gatewayType; - public GW1000Station(Cumulus cumulus) : base(cumulus) { cumulus.Units.AirQualityUnitText = "µg/m³"; @@ -663,6 +662,7 @@ private bool PrintSensorInfoNew(byte[] data, int idx) batt += " dummy value?"; } } + break; case "WH65": @@ -722,6 +722,8 @@ private bool PrintSensorInfoNew(byte[] data, int idx) if (batt.Contains("Low")) batteryLow = true; + SensorReception[type] = data[sigPos]; + cumulus.LogDebugMessage($" - {type} sensor id = {id} signal = {data[sigPos]} battery = {batt}"); } catch (Exception ex) diff --git a/CumulusMX/WeatherStation.cs b/CumulusMX/WeatherStation.cs index 84b8e566..8b1f59ba 100644 --- a/CumulusMX/WeatherStation.cs +++ b/CumulusMX/WeatherStation.cs @@ -427,6 +427,8 @@ public WeatherStation(Cumulus cumulus) var rnd = new Random(); versionCheckTime = new DateTime(1, 1, 1, rnd.Next(0, 23), rnd.Next(0, 59), 0); + + SensorReception = new Dictionary(); } public void ReloadFailedMySQLCommands() @@ -5866,6 +5868,8 @@ private int getShortestAngle(int bearing1, int bearing2) public string DavisFirmwareVersion = "???"; public string GW1000FirmwareVersion = "???"; + public static Dictionary SensorReception { get; set; } + //private bool manualftp; public void WriteYesterdayFile(DateTime logdate) diff --git a/CumulusMX/webtags.cs b/CumulusMX/webtags.cs index 7addc419..7ae55780 100644 --- a/CumulusMX/webtags.cs +++ b/CumulusMX/webtags.cs @@ -106,7 +106,7 @@ private static string CheckRc(string val, Dictionary tagParams) } } - private static string CheckRcDp(double val, Dictionary tagParams, int decimals, string format=null) + private static string CheckRcDp(double val, Dictionary tagParams, int decimals, string format = null) { string ret; try @@ -248,21 +248,21 @@ private double CheckWindRunUnit(double val, Dictionary tagParams private double GetSnowDepth(DateTime day) - { - double depth; - try - { - var result = cumulus.DiaryDB.Query("SELECT * FROM DiaryData WHERE Timestamp = ?", day.Date); + { + double depth; + try + { + var result = cumulus.DiaryDB.Query("SELECT * FROM DiaryData WHERE Timestamp = ?", day.Date); - depth = result.Count == 1 ? result[0].snowDepth : 0; - } - catch(Exception e) - { - cumulus.LogMessage("Error reading diary database: " + e.Message); - depth = 0; - } - return depth; - } + depth = result.Count == 1 ? result[0].snowDepth : 0; + } + catch (Exception e) + { + cumulus.LogMessage("Error reading diary database: " + e.Message); + depth = 0; + } + return depth; + } private int GetSnowLying(DateTime day) { @@ -310,7 +310,7 @@ private static string EncodeForJs(string aStr) } - private DateTime GetRecentTs(Dictionary tagParams) + private DateTime GetRecentTs(Dictionary tagParams) { var daysagostr = tagParams.Get("d"); var hoursagostr = tagParams.Get("h"); @@ -331,7 +331,7 @@ private DateTime GetRecentTs(Dictionary tagParams) { try { - minsago += (Convert.ToInt32(hoursagostr)*60); + minsago += (Convert.ToInt32(hoursagostr) * 60); } catch { @@ -342,7 +342,7 @@ private DateTime GetRecentTs(Dictionary tagParams) { try { - minsago += (Convert.ToInt32(daysagostr)*1440); + minsago += (Convert.ToInt32(daysagostr) * 1440); } catch { @@ -356,7 +356,7 @@ private DateTime GetRecentTs(Dictionary tagParams) return DateTime.Now.AddMinutes(-minsago); } - private int GetMonthParam(Dictionary tagParams) + private int GetMonthParam(Dictionary tagParams) { int month; var monthstr = tagParams.Get("mon"); @@ -402,7 +402,7 @@ public string GetCurrCondText() return res; } - private string GetFormattedDateTime(DateTime dt, Dictionary tagParams) + private string GetFormattedDateTime(DateTime dt, Dictionary tagParams) { string s; string dtformat = tagParams.Get("format"); @@ -436,7 +436,7 @@ private string GetFormattedDateTime(DateTime dt, Dictionary tagPa return s; } - private string GetFormattedDateTime(DateTime dt, string defaultFormat, Dictionary tagParams) + private string GetFormattedDateTime(DateTime dt, string defaultFormat, Dictionary tagParams) { string s; if (dt <= cumulus.defaultRecordTS) @@ -463,7 +463,7 @@ private string GetFormattedDateTime(DateTime dt, string defaultFormat, Dictionar return s; } - private string GetFormattedDateTime(TimeSpan ts, string defaultFormat, Dictionary tagParams) + private string GetFormattedDateTime(TimeSpan ts, string defaultFormat, Dictionary tagParams) { DateTime dt = DateTime.MinValue.Add(ts); @@ -508,32 +508,32 @@ private string GetMonthlyAlltimeTSStr(int identifier, int month, string format) } */ - private string Tagwlatest(Dictionary tagParams) + private string Tagwlatest(Dictionary tagParams) { return CheckRcDp(CheckWindUnit(station.WindLatest, tagParams), tagParams, cumulus.WindDPlaces); } - private string Tagwindrun(Dictionary tagParams) + private string Tagwindrun(Dictionary tagParams) { return CheckRcDp(CheckWindRunUnit(station.WindRunToday, tagParams), tagParams, cumulus.WindRunDPlaces); } - private string Tagwspeed(Dictionary tagParams) + private string Tagwspeed(Dictionary tagParams) { return CheckRcDp(CheckWindUnit(station.WindAverage, tagParams), tagParams, cumulus.WindAvgDPlaces); } - private string Tagcurrentwdir(Dictionary tagParams) + private string Tagcurrentwdir(Dictionary tagParams) { return station.CompassPoint(station.Bearing); } - private string Tagwdir(Dictionary tagParams) + private string Tagwdir(Dictionary tagParams) { return station.CompassPoint(station.AvgBearing); } - private string Tagwgust(Dictionary tagParams) + private string Tagwgust(Dictionary tagParams) { return CheckRcDp(CheckWindUnit(station.RecentMaxGust, tagParams), tagParams, cumulus.WindDPlaces); } @@ -551,22 +551,22 @@ private string TagwindAvg(Dictionary tagParams) return CheckRcDp(CheckWindUnit(hours > 0.25 ? station.WindRunToday / timeToday : 0, tagParams), tagParams, cumulus.WindAvgDPlaces); } - private string Tagwchill(Dictionary tagParams) + private string Tagwchill(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.WindChill, tagParams), tagParams, cumulus.TempDPlaces); } - private string Tagrrate(Dictionary tagParams) + private string Tagrrate(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.RainRate, tagParams), tagParams, cumulus.RainDPlaces); } - private string TagStormRain(Dictionary tagParams) + private string TagStormRain(Dictionary tagParams) { return CheckRcDp(station.StormRain, tagParams, cumulus.RainDPlaces); } - private string TagStormRainStart(Dictionary tagParams) + private string TagStormRainStart(Dictionary tagParams) { if (station.StartOfStorm == DateTime.MinValue) @@ -579,12 +579,12 @@ private string TagStormRainStart(Dictionary tagParams) return station.StartOfStorm.ToString(dtformat); } - private string Tagtomorrowdaylength(Dictionary tagParams) + private string Tagtomorrowdaylength(Dictionary tagParams) { return cumulus.TomorrowDayLengthText; } - private string TagwindrunY(Dictionary tagParams) + private string TagwindrunY(Dictionary tagParams) { return CheckRcDp(CheckWindRunUnit(station.YesterdayWindRun, tagParams), tagParams, cumulus.WindRunDPlaces); } @@ -596,27 +596,27 @@ private string TagwindAvgY(Dictionary tagParams) } - private string Tagheatdegdays(Dictionary tagParams) + private string Tagheatdegdays(Dictionary tagParams) { return CheckRcDp(CheckTempUnitAbs(station.HeatingDegreeDays, tagParams), tagParams, cumulus.TempDPlaces); } - private string Tagcooldegdays(Dictionary tagParams) + private string Tagcooldegdays(Dictionary tagParams) { return CheckRcDp(CheckTempUnitAbs(station.CoolingDegreeDays, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagheatdegdaysY(Dictionary tagParams) + private string TagheatdegdaysY(Dictionary tagParams) { return CheckRcDp(CheckTempUnitAbs(station.YestHeatingDegreeDays, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagcooldegdaysY(Dictionary tagParams) + private string TagcooldegdaysY(Dictionary tagParams) { return CheckRcDp(CheckTempUnitAbs(station.YestCoolingDegreeDays, tagParams), tagParams, cumulus.TempDPlaces); } - private string Tagpresstrendval(Dictionary tagParams) + private string Tagpresstrendval(Dictionary tagParams) { return CheckRcDp(CheckPressUnit(station.presstrendval, tagParams), tagParams, cumulus.PressDPlaces); } @@ -627,7 +627,7 @@ private string Tagpresstrendsigned(Dictionary tagParams) } - private string TagPressChangeLast3Hours(Dictionary tagParams) + private string TagPressChangeLast3Hours(Dictionary tagParams) { return CheckRcDp(CheckPressUnit(station.presstrendval * 3, tagParams), tagParams, cumulus.PressDPlaces); } @@ -638,48 +638,48 @@ private string TagTempChangeLastHour(Dictionary tagParams) } - private string Tagdew(Dictionary tagParams) + private string Tagdew(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.OutdoorDewpoint, tagParams), tagParams, cumulus.TempDPlaces); } - private string Tagwetbulb(Dictionary tagParams) + private string Tagwetbulb(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.WetBulb, tagParams), tagParams, cumulus.TempDPlaces); } - private string Tagcloudbase(Dictionary tagParams) + private string Tagcloudbase(Dictionary tagParams) { return station.CloudBase + (cumulus.CloudBaseInFeet ? " ft" : " m"); } - private string Tagcloudbaseunit(Dictionary tagParams) + private string Tagcloudbaseunit(Dictionary tagParams) { return cumulus.CloudBaseInFeet ? "ft" : "m"; } - private string Tagcloudbasevalue(Dictionary tagParams) + private string Tagcloudbasevalue(Dictionary tagParams) { return station.CloudBase.ToString(); } - private string TagTime(Dictionary tagParams) + private string TagTime(Dictionary tagParams) { return GetFormattedDateTime(DateTime.Now, "HH:mm\" on \"dd MMMM yyyy", tagParams); } - private static string TagDaysSince30Dec1899(Dictionary tagParams) + private static string TagDaysSince30Dec1899(Dictionary tagParams) { - DateTime startDate = new DateTime(1899,12,30); + DateTime startDate = new DateTime(1899, 12, 30); return ((DateTime.Now - startDate).TotalDays).ToString(); } - private string TagTimeUtc(Dictionary tagParams) + private string TagTimeUtc(Dictionary tagParams) { return GetFormattedDateTime(DateTime.UtcNow, "HH:mm\" on \"dd MMMM yyyy", tagParams); } - private static string TagTimehhmmss(Dictionary tagParams) + private static string TagTimehhmmss(Dictionary tagParams) { return DateTime.Now.ToString("HH:mm:ss"); } @@ -694,90 +694,90 @@ private static string TagTimeUnix(Dictionary tagParams) return DateTime.Now.ToUnixEpochDate().ToString(); } - private string TagDate(Dictionary tagParams) + private string TagDate(Dictionary tagParams) { return GetFormattedDateTime(DateTime.Now, "d", tagParams); } - private string TagYesterday(Dictionary tagParams) + private string TagYesterday(Dictionary tagParams) { var yesterday = DateTime.Now.AddDays(-1); return GetFormattedDateTime(yesterday, "d", tagParams); } - private string TagMetDate(Dictionary tagParams) + private string TagMetDate(Dictionary tagParams) { int offset = cumulus.GetHourInc(); return GetFormattedDateTime(DateTime.Now.AddHours(offset), "d", tagParams); } - private string TagMetDateYesterday(Dictionary tagParams) + private string TagMetDateYesterday(Dictionary tagParams) { int offset = cumulus.GetHourInc(); return GetFormattedDateTime(DateTime.Now.AddHours(offset).AddDays(-1), "d", tagParams); } - private static string TagDay(Dictionary tagParams) + private static string TagDay(Dictionary tagParams) { return DateTime.Now.ToString("dd"); } - private static string TagDayname(Dictionary tagParams) + private static string TagDayname(Dictionary tagParams) { return DateTime.Now.ToString("dddd"); } - private static string TagShortdayname(Dictionary tagParams) + private static string TagShortdayname(Dictionary tagParams) { return DateTime.Now.ToString("ddd"); } - private static string TagMonth(Dictionary tagParams) + private static string TagMonth(Dictionary tagParams) { return DateTime.Now.ToString("MM"); } - private static string TagMonthname(Dictionary tagParams) + private static string TagMonthname(Dictionary tagParams) { return DateTime.Now.ToString("MMMM"); } - private static string TagShortmonthname(Dictionary tagParams) + private static string TagShortmonthname(Dictionary tagParams) { return DateTime.Now.ToString("MMM"); } - private static string TagYear(Dictionary tagParams) + private static string TagYear(Dictionary tagParams) { return DateTime.Now.Year.ToString(); } - private static string TagShortyear(Dictionary tagParams) + private static string TagShortyear(Dictionary tagParams) { return DateTime.Now.ToString("yy"); } - private static string TagHour(Dictionary tagParams) + private static string TagHour(Dictionary tagParams) { return DateTime.Now.ToString("HH"); } - private static string TagMinute(Dictionary tagParams) + private static string TagMinute(Dictionary tagParams) { return DateTime.Now.ToString("mm"); } - private string Tagforecastnumber(Dictionary tagParams) + private string Tagforecastnumber(Dictionary tagParams) { return station.Forecastnumber.ToString(); } - private string Tagforecast(Dictionary tagParams) + private string Tagforecast(Dictionary tagParams) { return station.forecaststr; } - private string Tagforecastenc(Dictionary tagParams) + private string Tagforecastenc(Dictionary tagParams) { return EncodeForWeb(station.forecaststr); } @@ -787,7 +787,7 @@ private string TagforecastJsEnc(Dictionary tagParams) return EncodeForJs(station.forecaststr); } - private string Tagcumulusforecast(Dictionary tagParams) + private string Tagcumulusforecast(Dictionary tagParams) { return station.CumulusForecast; } @@ -802,12 +802,12 @@ private string TagcumulusforecastJsEnc(Dictionary tagParams) return EncodeForJs(station.CumulusForecast); } - private string Tagwsforecast(Dictionary tagParams) + private string Tagwsforecast(Dictionary tagParams) { return station.wsforecast; } - private string Tagwsforecastenc(Dictionary tagParams) + private string Tagwsforecastenc(Dictionary tagParams) { return EncodeForWeb(station.wsforecast); } @@ -818,32 +818,32 @@ private string TagwsforecastJsEnc(Dictionary tagParams) } - private string Tagtemp(Dictionary tagParams) + private string Tagtemp(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.OutdoorTemperature, tagParams), tagParams, cumulus.TempDPlaces); } - private string Tagtemprange(Dictionary tagParams) + private string Tagtemprange(Dictionary tagParams) { return CheckRcDp(CheckTempUnitAbs(station.HiLoToday.TempRange, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagtemprangeY(Dictionary tagParams) + private string TagtemprangeY(Dictionary tagParams) { return CheckRcDp(CheckTempUnitAbs(station.HiLoYest.TempRange, tagParams), tagParams, cumulus.TempDPlaces); } - private string Tagavgtemp(Dictionary tagParams) + private string Tagavgtemp(Dictionary tagParams) { - return CheckRcDp(CheckTempUnit(station.TempTotalToday/station.tempsamplestoday, tagParams), tagParams, cumulus.TempDPlaces); + return CheckRcDp(CheckTempUnit(station.TempTotalToday / station.tempsamplestoday, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagavgtempY(Dictionary tagParams) + private string TagavgtempY(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.YestAvgTemp, tagParams), tagParams, cumulus.TempDPlaces); } - private string Tagapptemp(Dictionary tagParams) + private string Tagapptemp(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ApparentTemperature, tagParams), tagParams, cumulus.TempDPlaces); } @@ -853,7 +853,7 @@ private string Tagfeelsliketemp(Dictionary tagParams) return CheckRcDp(CheckTempUnit(station.FeelsLike, tagParams), tagParams, cumulus.TempDPlaces); } - private string Tagtemptrend(Dictionary tagParams) + private string Tagtemptrend(Dictionary tagParams) { return CheckRcDp(CheckTempUnitAbs(station.temptrendval, tagParams), tagParams, cumulus.TempDPlaces); } @@ -863,12 +863,12 @@ private string Tagtemptrendsigned(Dictionary tagParams) return CheckRcDp(CheckTempUnitAbs(station.temptrendval, tagParams), tagParams, cumulus.TempDPlaces, cumulus.TempTrendFormat); } - private string Tagtemptrendtext(Dictionary tagParams) + private string Tagtemptrendtext(Dictionary tagParams) { string text; if (Math.Abs(station.temptrendval) < 0.001) { - text = cumulus.Trans.Steady; + text = cumulus.Trans.Steady; } else if (station.temptrendval > 0) { @@ -881,7 +881,7 @@ private string Tagtemptrendtext(Dictionary tagParams) return text; } - private string Tagtemptrendenglish(Dictionary tagParams) + private string Tagtemptrendenglish(Dictionary tagParams) { if (Math.Abs(station.temptrendval) < 0.001) { @@ -891,27 +891,27 @@ private string Tagtemptrendenglish(Dictionary tagParams) return station.temptrendval > 0 ? "Rising" : "Falling"; } - private string Tagheatindex(Dictionary tagParams) + private string Tagheatindex(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.HeatIndex, tagParams), tagParams, cumulus.TempDPlaces); } - private string Taghum(Dictionary tagParams) + private string Taghum(Dictionary tagParams) { return station.OutdoorHumidity.ToString(); } - private string Taghumidex(Dictionary tagParams) + private string Taghumidex(Dictionary tagParams) { return CheckRcDp(station.Humidex, tagParams, cumulus.TempDPlaces); } - private string Tagpress(Dictionary tagParams) + private string Tagpress(Dictionary tagParams) { return CheckRcDp(CheckPressUnit(station.Pressure, tagParams), tagParams, cumulus.PressDPlaces); } - private string Tagaltimeterpressure(Dictionary tagParams) + private string Tagaltimeterpressure(Dictionary tagParams) { return CheckRcDp(CheckPressUnit(station.AltimeterPressure, tagParams), tagParams, cumulus.PressDPlaces); } @@ -922,12 +922,12 @@ private string Tagstationpressure(Dictionary tagParams) } - private string Tagpresstrend(Dictionary tagParams) + private string Tagpresstrend(Dictionary tagParams) { return station.Presstrendstr; } - private string Tagpresstrendenglish(Dictionary tagParams) + private string Tagpresstrendenglish(Dictionary tagParams) { if (Math.Abs(station.presstrendval) < 0.0001) { @@ -937,62 +937,62 @@ private string Tagpresstrendenglish(Dictionary tagParams) return station.presstrendval > 0 ? "Rising" : "Falling"; } - private string Tagbearing(Dictionary tagParams) + private string Tagbearing(Dictionary tagParams) { return station.Bearing.ToString(); } - private string Tagavgbearing(Dictionary tagParams) + private string Tagavgbearing(Dictionary tagParams) { return station.AvgBearing.ToString(); } - private string TagBearingRangeFrom(Dictionary tagParams) + private string TagBearingRangeFrom(Dictionary tagParams) { return station.BearingRangeFrom.ToString(); } - private string TagBearingRangeTo(Dictionary tagParams) + private string TagBearingRangeTo(Dictionary tagParams) { return station.BearingRangeTo.ToString(); } - private string TagBearingRangeFrom10(Dictionary tagParams) + private string TagBearingRangeFrom10(Dictionary tagParams) { return station.BearingRangeFrom10.ToString("D3"); } - private string TagBearingRangeTo10(Dictionary tagParams) + private string TagBearingRangeTo10(Dictionary tagParams) { return station.BearingRangeTo10.ToString("D3"); } - private string Tagdomwindbearing(Dictionary tagParams) + private string Tagdomwindbearing(Dictionary tagParams) { return station.DominantWindBearing.ToString(); } - private string Tagdomwinddir(Dictionary tagParams) + private string Tagdomwinddir(Dictionary tagParams) { return station.CompassPoint(station.DominantWindBearing); } - private string TagdomwindbearingY(Dictionary tagParams) + private string TagdomwindbearingY(Dictionary tagParams) { return station.YestDominantWindBearing.ToString(); } - private string TagdomwinddirY(Dictionary tagParams) + private string TagdomwinddirY(Dictionary tagParams) { return station.CompassPoint(station.YestDominantWindBearing); } - private string Tagbeaufort(Dictionary tagParams) + private string Tagbeaufort(Dictionary tagParams) { return "F" + cumulus.Beaufort(station.WindAverage); } - private string Tagbeaufortnumber(Dictionary tagParams) + private string Tagbeaufortnumber(Dictionary tagParams) { return cumulus.Beaufort(station.WindAverage); } @@ -1002,7 +1002,7 @@ private string Tagbeaudesc(Dictionary tagParams) return cumulus.BeaufortDesc(station.WindAverage); } - private string Tagwdirdata(Dictionary tagParams) + private string Tagwdirdata(Dictionary tagParams) { var sb = new StringBuilder(station.windbears[0].ToString()); @@ -1014,7 +1014,7 @@ private string Tagwdirdata(Dictionary tagParams) return sb.ToString(); } - private string Tagwspddata(Dictionary tagParams) + private string Tagwspddata(Dictionary tagParams) { var sb = new StringBuilder((station.windspeeds[0]).ToString(cumulus.WindFormat, CultureInfo.InvariantCulture)); for (var i = 1; i < station.numwindvalues; i++) @@ -1025,17 +1025,17 @@ private string Tagwspddata(Dictionary tagParams) return sb.ToString(); } - private string TagWindSampleCount(Dictionary tagParams) + private string TagWindSampleCount(Dictionary tagParams) { return station.numwindvalues.ToString(); } - private string Tagnextwindindex(Dictionary tagParams) + private string Tagnextwindindex(Dictionary tagParams) { return station.nextwindvalue.ToString(); } - private string TagWindRoseData(Dictionary tagParams) + private string TagWindRoseData(Dictionary tagParams) { // no need to use multiplier as the rose is all relative var sb = new StringBuilder(station.windcounts[0].ToString(cumulus.WindFormat, CultureInfo.InvariantCulture)); @@ -1048,52 +1048,52 @@ private string TagWindRoseData(Dictionary tagParams) return sb.ToString(); } - private string TagWindRosePoints(Dictionary tagParams) + private string TagWindRosePoints(Dictionary tagParams) { return cumulus.NumWindRosePoints.ToString(); } - private string Tagrfall(Dictionary tagParams) + private string Tagrfall(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.RainToday, tagParams), tagParams, cumulus.RainDPlaces); } - private string Tagrmidnight(Dictionary tagParams) + private string Tagrmidnight(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.RainSinceMidnight, tagParams), tagParams, cumulus.RainDPlaces); } - private string Tagrmonth(Dictionary tagParams) + private string Tagrmonth(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.RainMonth, tagParams), tagParams, cumulus.RainDPlaces); } - private string Tagrhour(Dictionary tagParams) + private string Tagrhour(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.RainLastHour, tagParams), tagParams, cumulus.RainDPlaces); } - private string Tagr24Hour(Dictionary tagParams) + private string Tagr24Hour(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.RainLast24Hour, tagParams), tagParams, cumulus.RainDPlaces); } - private string Tagryear(Dictionary tagParams) + private string Tagryear(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.RainYear, tagParams), tagParams, cumulus.RainDPlaces); } - private string Taginhum(Dictionary tagParams) + private string Taginhum(Dictionary tagParams) { return station.IndoorHumidity.ToString(); } - private string Tagintemp(Dictionary tagParams) + private string Tagintemp(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.IndoorTemperature, tagParams), tagParams, cumulus.TempDPlaces); } - private string Tagbattery(Dictionary tagParams) + private string Tagbattery(Dictionary tagParams) { return CheckRc(station.ConBatText, tagParams); } @@ -1103,7 +1103,7 @@ private string TagConsoleSupplyV(Dictionary tagParams) return CheckRc(station.ConSupplyVoltageText, tagParams); } - private string Tagtxbattery(Dictionary tagParams) + private string Tagtxbattery(Dictionary tagParams) { if (string.IsNullOrEmpty(station.TxBatText)) { @@ -1145,7 +1145,7 @@ private string TagMulticastGoodPct(Dictionary tagParams) { try { - return (station.multicastsGood / (float)(station.multicastsBad + station.multicastsGood) * 100).ToString("0.00"); + return (station.multicastsGood / (float) (station.multicastsBad + station.multicastsGood) * 100).ToString("0.00"); } catch { @@ -1456,7 +1456,7 @@ private string AirLinkPct_NowcastOut(Dictionary tagParams) } - private string Tagsnowdepth(Dictionary tagParams) + private string Tagsnowdepth(Dictionary tagParams) { var ts = DateTime.Now.Hour < cumulus.SnowDepthHour ? DateTime.Now.AddDays(-1) : DateTime.Now; return CheckRc(GetSnowDepth(ts.Date).ToString(), tagParams); @@ -1474,12 +1474,12 @@ private string Tagsnowfalling(Dictionary tagParams) return GetSnowFalling(ts.Date).ToString(); } - private string Tagnewrecord(Dictionary tagParams) + private string Tagnewrecord(Dictionary tagParams) { return station.AlltimeRecordTimestamp < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagTempRecordSet(Dictionary tagParams) + private string TagTempRecordSet(Dictionary tagParams) { var threshold = DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs); if (station.AllTime.HighTemp.Ts >= threshold || @@ -1503,7 +1503,7 @@ private string TagTempRecordSet(Dictionary tagParams) return "0"; } - private string TagWindRecordSet(Dictionary tagParams) + private string TagWindRecordSet(Dictionary tagParams) { var threshold = DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs); if (station.AllTime.HighGust.Ts >= threshold || @@ -1515,7 +1515,7 @@ private string TagWindRecordSet(Dictionary tagParams) return "0"; } - private string TagRainRecordSet(Dictionary tagParams) + private string TagRainRecordSet(Dictionary tagParams) { var threshold = DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs); if (station.AllTime.HighRainRate.Ts >= threshold || @@ -1531,7 +1531,7 @@ private string TagRainRecordSet(Dictionary tagParams) return "0"; } - private string TagHumidityRecordSet(Dictionary tagParams) + private string TagHumidityRecordSet(Dictionary tagParams) { var threshold = DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs); if (station.AllTime.HighHumidity.Ts >= threshold || @@ -1542,7 +1542,7 @@ private string TagHumidityRecordSet(Dictionary tagParams) return "0"; } - private string TagPressureRecordSet(Dictionary tagParams) + private string TagPressureRecordSet(Dictionary tagParams) { var threshold = DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs); if (station.AllTime.LowPress.Ts >= threshold || @@ -1553,12 +1553,12 @@ private string TagPressureRecordSet(Dictionary tagParams) return "0"; } - private string TagHighTempRecordSet(Dictionary tagParams) + private string TagHighTempRecordSet(Dictionary tagParams) { return station.AllTime.HighTemp.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagLowTempRecordSet(Dictionary tagParams) + private string TagLowTempRecordSet(Dictionary tagParams) { return station.AllTime.LowTemp.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } @@ -1588,57 +1588,57 @@ private string TagHighHumidexRecordSet(Dictionary tagParams) return station.AllTime.HighHumidex.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagHighHeatIndexRecordSet(Dictionary tagParams) + private string TagHighHeatIndexRecordSet(Dictionary tagParams) { return station.AllTime.HighHeatIndex.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagLowWindChillRecordSet(Dictionary tagParams) + private string TagLowWindChillRecordSet(Dictionary tagParams) { return station.AllTime.LowChill.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagHighMinTempRecordSet(Dictionary tagParams) + private string TagHighMinTempRecordSet(Dictionary tagParams) { return station.AllTime.HighMinTemp.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagLowMaxTempRecordSet(Dictionary tagParams) + private string TagLowMaxTempRecordSet(Dictionary tagParams) { return station.AllTime.LowMaxTemp.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagHighDewPointRecordSet(Dictionary tagParams) + private string TagHighDewPointRecordSet(Dictionary tagParams) { return station.AllTime.HighDewPoint.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagLowDewPointRecordSet(Dictionary tagParams) + private string TagLowDewPointRecordSet(Dictionary tagParams) { return station.AllTime.LowDewPoint.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagHighWindGustRecordSet(Dictionary tagParams) + private string TagHighWindGustRecordSet(Dictionary tagParams) { return station.AllTime.HighGust.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagHighWindSpeedRecordSet(Dictionary tagParams) + private string TagHighWindSpeedRecordSet(Dictionary tagParams) { return station.AllTime.HighWind.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagHighRainRateRecordSet(Dictionary tagParams) + private string TagHighRainRateRecordSet(Dictionary tagParams) { return station.AllTime.HighRainRate.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagHighHourlyRainRecordSet(Dictionary tagParams) + private string TagHighHourlyRainRecordSet(Dictionary tagParams) { return station.AllTime.HourlyRain.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagHighDailyRainRecordSet(Dictionary tagParams) + private string TagHighDailyRainRecordSet(Dictionary tagParams) { return station.AllTime.DailyRain.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } @@ -1648,78 +1648,78 @@ private string TagHighRain24HourRecordSet(Dictionary tagParams) return station.AllTime.HighRain24Hours.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagHighMonthlyRainRecordSet(Dictionary tagParams) + private string TagHighMonthlyRainRecordSet(Dictionary tagParams) { return station.AllTime.MonthlyRain.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagHighHumidityRecordSet(Dictionary tagParams) + private string TagHighHumidityRecordSet(Dictionary tagParams) { return station.AllTime.HighHumidity.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagHighWindrunRecordSet(Dictionary tagParams) + private string TagHighWindrunRecordSet(Dictionary tagParams) { return station.AllTime.HighWindRun.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagLowHumidityRecordSet(Dictionary tagParams) + private string TagLowHumidityRecordSet(Dictionary tagParams) { return station.AllTime.LowHumidity.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagHighPressureRecordSet(Dictionary tagParams) + private string TagHighPressureRecordSet(Dictionary tagParams) { return station.AllTime.HighPress.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagLowPressureRecordSet(Dictionary tagParams) + private string TagLowPressureRecordSet(Dictionary tagParams) { return station.AllTime.LowPress.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagLongestDryPeriodRecordSet(Dictionary tagParams) + private string TagLongestDryPeriodRecordSet(Dictionary tagParams) { return station.AllTime.LongestDryPeriod.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagLongestWetPeriodRecordSet(Dictionary tagParams) + private string TagLongestWetPeriodRecordSet(Dictionary tagParams) { return station.AllTime.LongestWetPeriod.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagHighTempRangeRecordSet(Dictionary tagParams) + private string TagHighTempRangeRecordSet(Dictionary tagParams) { return station.AllTime.HighDailyTempRange.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string TagLowTempRangeRecordSet(Dictionary tagParams) + private string TagLowTempRangeRecordSet(Dictionary tagParams) { return station.AllTime.LowDailyTempRange.Ts < DateTime.Now.AddHours(-cumulus.RecordSetTimeoutHrs) ? "0" : "1"; } - private string Tagerrorlight(Dictionary tagParams) + private string Tagerrorlight(Dictionary tagParams) { // TODO return "0"; } - private string TagtempTh(Dictionary tagParams) + private string TagtempTh(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.HiLoToday.HighTemp, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagTtempTh(Dictionary tagParams) + private string TagTtempTh(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoToday.HighTempTime, "HH:mm", tagParams); } - private string TagtempTl(Dictionary tagParams) + private string TagtempTl(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.HiLoToday.LowTemp, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagTtempTl(Dictionary tagParams) + private string TagTtempTl(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoToday.LowTempTime, "HH:mm", tagParams); } @@ -1749,52 +1749,52 @@ private string TagtempMidnightRangeT(Dictionary tagParams) return CheckRcDp(CheckTempUnitAbs((station.HiLoTodayMidnight.HighTemp - station.HiLoTodayMidnight.LowTemp), tagParams), tagParams, cumulus.TempDPlaces); } - private string TagSolarTh(Dictionary tagParams) + private string TagSolarTh(Dictionary tagParams) { - return ((int)station.HiLoToday.HighSolar).ToString(); + return ((int) station.HiLoToday.HighSolar).ToString(); } - private string TagTsolarTh(Dictionary tagParams) + private string TagTsolarTh(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoToday.HighSolarTime, "HH:mm", tagParams); } - private string TagUvth(Dictionary tagParams) + private string TagUvth(Dictionary tagParams) { return CheckRcDp(station.HiLoToday.HighUv, tagParams, cumulus.UVDPlaces); } - private string TagTuvth(Dictionary tagParams) + private string TagTuvth(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoToday.HighUvTime, "HH:mm", tagParams); } - private string TagapptempTh(Dictionary tagParams) + private string TagapptempTh(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.HiLoToday.HighAppTemp, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagRCapptempTh(Dictionary tagParams) + private string TagRCapptempTh(Dictionary tagParams) { return ReplaceCommas(TagapptempTh(tagParams)); } - private string TagTapptempTh(Dictionary tagParams) + private string TagTapptempTh(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoToday.HighAppTempTime, "HH:mm", tagParams); } - private string TagapptempTl(Dictionary tagParams) + private string TagapptempTl(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.HiLoToday.LowAppTemp, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagRCapptempTl(Dictionary tagParams) + private string TagRCapptempTl(Dictionary tagParams) { return ReplaceCommas(TagapptempTl(tagParams)); } - private string TagTapptempTl(Dictionary tagParams) + private string TagTapptempTl(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoToday.LowAppTempTime, "HH:mm", tagParams); } @@ -1829,152 +1829,152 @@ private string TagThumidexTh(Dictionary tagParams) return GetFormattedDateTime(station.HiLoToday.HighHumidexTime, "HH:mm", tagParams); } - private string TagdewpointTh(Dictionary tagParams) + private string TagdewpointTh(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.HiLoToday.HighDewPoint, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagRCdewpointTh(Dictionary tagParams) + private string TagRCdewpointTh(Dictionary tagParams) { - return ReplaceCommas(TagdewpointTh(tagParams)); + return ReplaceCommas(TagdewpointTh(tagParams)); } - private string TagTdewpointTh(Dictionary tagParams) + private string TagTdewpointTh(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoToday.HighDewPointTime, "HH:mm", tagParams); } - private string TagdewpointTl(Dictionary tagParams) + private string TagdewpointTl(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.HiLoToday.LowDewPoint, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagRCdewpointTl(Dictionary tagParams) + private string TagRCdewpointTl(Dictionary tagParams) { return ReplaceCommas(TagdewpointTl(tagParams)); } - private string TagTdewpointTl(Dictionary tagParams) + private string TagTdewpointTl(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoToday.LowDewPointTime, "HH:mm", tagParams); } - private string TagwchillTl(Dictionary tagParams) + private string TagwchillTl(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.HiLoToday.LowWindChill, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagRCwchillTl(Dictionary tagParams) + private string TagRCwchillTl(Dictionary tagParams) { return ReplaceCommas(TagwchillTl(tagParams)); } - private string TagTwchillTl(Dictionary tagParams) + private string TagTwchillTl(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoToday.LowWindChillTime, "HH:mm", tagParams); } - private string TagheatindexTh(Dictionary tagParams) + private string TagheatindexTh(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.HiLoToday.HighHeatIndex, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagRCheatindexTh(Dictionary tagParams) + private string TagRCheatindexTh(Dictionary tagParams) { return ReplaceCommas(TagheatindexTh(tagParams)); } - private string TagTheatindexTh(Dictionary tagParams) + private string TagTheatindexTh(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoToday.HighHeatIndexTime, "HH:mm", tagParams); } - private string TagheatindexYh(Dictionary tagParams) + private string TagheatindexYh(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.HiLoYest.HighHeatIndex, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagTheatindexYh(Dictionary tagParams) + private string TagTheatindexYh(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoYest.HighHeatIndexTime, "HH:mm", tagParams); } - private string TagpressTh(Dictionary tagParams) + private string TagpressTh(Dictionary tagParams) { return CheckRcDp(CheckPressUnit(station.HiLoToday.HighPress, tagParams), tagParams, cumulus.PressDPlaces); } - private string TagTpressTh(Dictionary tagParams) + private string TagTpressTh(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoToday.HighPressTime, "HH:mm", tagParams); } - private string TagpressTl(Dictionary tagParams) + private string TagpressTl(Dictionary tagParams) { return CheckRcDp(CheckPressUnit(station.HiLoToday.LowPress, tagParams), tagParams, cumulus.PressDPlaces); } - private string TagTpressTl(Dictionary tagParams) + private string TagTpressTl(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoToday.LowPressTime, "HH:mm", tagParams); } - private string TaghumTh(Dictionary tagParams) + private string TaghumTh(Dictionary tagParams) { return station.HiLoToday.HighHumidity.ToString(); } - private string TagThumTh(Dictionary tagParams) + private string TagThumTh(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoToday.HighHumidityTime, "HH:mm", tagParams); } - private string TaghumTl(Dictionary tagParams) + private string TaghumTl(Dictionary tagParams) { return station.HiLoToday.LowHumidity.ToString(); } - private string TagThumTl(Dictionary tagParams) + private string TagThumTl(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoToday.LowHumidityTime, "HH:mm", tagParams); } - private string TagwindTm(Dictionary tagParams) + private string TagwindTm(Dictionary tagParams) { return CheckRcDp(CheckWindUnit(station.HiLoToday.HighWind, tagParams), tagParams, cumulus.WindAvgDPlaces); } - private string TagTbeaufort(Dictionary tagParams) + private string TagTbeaufort(Dictionary tagParams) { return "F" + cumulus.Beaufort(station.HiLoToday.HighWind); } - private string TagTbeaufortnumber(Dictionary tagParams) + private string TagTbeaufortnumber(Dictionary tagParams) { return cumulus.Beaufort(station.HiLoToday.HighWind); } - private string TagTbeaudesc(Dictionary tagParams) + private string TagTbeaudesc(Dictionary tagParams) { return cumulus.BeaufortDesc(station.HiLoToday.HighWind); } - private string TagTwindTm(Dictionary tagParams) + private string TagTwindTm(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoToday.HighWindTime, "HH:mm", tagParams); } - private string TagwgustTm(Dictionary tagParams) + private string TagwgustTm(Dictionary tagParams) { return CheckRcDp(CheckWindUnit(station.HiLoToday.HighGust, tagParams), tagParams, cumulus.WindDPlaces); } - private string TagTwgustTm(Dictionary tagParams) + private string TagTwgustTm(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoToday.HighGustTime, "HH:mm", tagParams); } - private string TagbearingTm(Dictionary tagParams) + private string TagbearingTm(Dictionary tagParams) { return station.HiLoToday.HighGustBearing.ToString(); } @@ -1984,22 +1984,22 @@ private string TagdirectionTm(Dictionary tagParams) return station.CompassPoint(station.HiLoToday.HighGustBearing); } - private string TagrrateTm(Dictionary tagParams) + private string TagrrateTm(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.HiLoToday.HighRainRate, tagParams), tagParams, cumulus.RainDPlaces); } - private string TagTrrateTm(Dictionary tagParams) + private string TagTrrateTm(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoToday.HighRainRateTime, "HH:mm", tagParams); } - private string TaghourlyrainTh(Dictionary tagParams) + private string TaghourlyrainTh(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.HiLoToday.HighHourlyRain, tagParams), tagParams, cumulus.RainDPlaces); } - private string TagThourlyrainTh(Dictionary tagParams) + private string TagThourlyrainTh(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoToday.HighHourlyRainTime, "HH:mm", tagParams); } @@ -2014,12 +2014,12 @@ private string TagTrain24hourTh(Dictionary tagParams) return GetFormattedDateTime(station.HiLoToday.HighRain24hTime, "HH:mm", tagParams); } - private string TaghourlyrainYh(Dictionary tagParams) + private string TaghourlyrainYh(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.HiLoYest.HighHourlyRain, tagParams), tagParams, cumulus.RainDPlaces); } - private string TagThourlyrainYh(Dictionary tagParams) + private string TagThourlyrainYh(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoYest.HighHourlyRainTime, "HH:mm", tagParams); } @@ -2034,27 +2034,27 @@ private string TagTrain24hourYh(Dictionary tagParams) return GetFormattedDateTime(station.HiLoYest.HighRain24hTime, "HH:mm", tagParams); } - private string TagSolarYh(Dictionary tagParams) + private string TagSolarYh(Dictionary tagParams) { return station.HiLoYest.HighSolar.ToString("F0"); } - private string TagTsolarYh(Dictionary tagParams) + private string TagTsolarYh(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoYest.HighSolarTime, "HH:mm", tagParams); } - private string TagUvyh(Dictionary tagParams) + private string TagUvyh(Dictionary tagParams) { return CheckRcDp(station.HiLoYest.HighUv, tagParams, cumulus.UVDPlaces); } - private string TagTuvyh(Dictionary tagParams) + private string TagTuvyh(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoYest.HighUvTime, "HH:mm", tagParams); } - private string Tagrollovertime(Dictionary tagParams) + private string Tagrollovertime(Dictionary tagParams) { switch (cumulus.GetHourInc()) { @@ -2069,22 +2069,22 @@ private string Tagrollovertime(Dictionary tagParams) } } - private string TagRg11RainToday(Dictionary tagParams) + private string TagRg11RainToday(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.RG11RainToday, tagParams), tagParams, cumulus.RainDPlaces); } - private string TagRg11RainYest(Dictionary tagParams) + private string TagRg11RainYest(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.RG11RainYesterday, tagParams), tagParams, cumulus.RainDPlaces); } - private string Tagcurrcond(Dictionary tagParams) + private string Tagcurrcond(Dictionary tagParams) { return GetCurrCondText(); } - private string Tagcurrcondenc(Dictionary tagParams) + private string Tagcurrcondenc(Dictionary tagParams) { return EncodeForWeb(GetCurrCondText()); } @@ -2095,22 +2095,22 @@ private string TagcurrcondJsEnc(Dictionary tagParams) } - private string TagtempYh(Dictionary tagParams) + private string TagtempYh(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.HiLoYest.HighTemp, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagTtempYh(Dictionary tagParams) + private string TagTtempYh(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoYest.HighTempTime, "HH:mm", tagParams); } - private string TagtempYl(Dictionary tagParams) + private string TagtempYl(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.HiLoYest.LowTemp, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagTtempYl(Dictionary tagParams) + private string TagTtempYl(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoYest.LowTempTime, "HH:mm", tagParams); } @@ -2140,27 +2140,27 @@ private string TagtempMidnightRangeY(Dictionary tagParams) return CheckRcDp(CheckTempUnitAbs((station.HiLoYestMidnight.HighTemp - station.HiLoYestMidnight.LowTemp), tagParams), tagParams, cumulus.TempDPlaces); } - private string TagapptempYh(Dictionary tagParams) + private string TagapptempYh(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.HiLoYest.HighAppTemp, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagTapptempYh(Dictionary tagParams) + private string TagTapptempYh(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoYest.HighAppTempTime, "HH:mm", tagParams); } - private string TagapptempYl(Dictionary tagParams) + private string TagapptempYl(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.HiLoYest.LowAppTemp, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagTapptempYl(Dictionary tagParams) + private string TagTapptempYl(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoYest.LowAppTempTime, "HH:mm", tagParams); } - private string TagdewpointYh(Dictionary tagParams) + private string TagdewpointYh(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.HiLoYest.HighDewPoint, tagParams), tagParams, cumulus.TempDPlaces); } @@ -2195,168 +2195,168 @@ private string TagThumidexYh(Dictionary tagParams) return GetFormattedDateTime(station.HiLoYest.HighHumidexTime, "HH:mm", tagParams); } - private string TagTdewpointYh(Dictionary tagParams) + private string TagTdewpointYh(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoYest.HighDewPointTime, "HH:mm", tagParams); } - private string TagdewpointYl(Dictionary tagParams) + private string TagdewpointYl(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.HiLoYest.LowDewPoint, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagTdewpointYl(Dictionary tagParams) + private string TagTdewpointYl(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoYest.LowDewPointTime, "HH:mm", tagParams); } - private string TagwchillYl(Dictionary tagParams) + private string TagwchillYl(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.HiLoYest.LowWindChill, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagTwchillYl(Dictionary tagParams) + private string TagTwchillYl(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoYest.LowWindChillTime, "HH:mm", tagParams); } - private string TagpressYh(Dictionary tagParams) + private string TagpressYh(Dictionary tagParams) { return CheckRcDp(CheckPressUnit(station.HiLoYest.HighPress, tagParams), tagParams, cumulus.PressDPlaces); } - private string TagTpressYh(Dictionary tagParams) + private string TagTpressYh(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoYest.HighPressTime, "HH:mm", tagParams); } - private string TagpressYl(Dictionary tagParams) + private string TagpressYl(Dictionary tagParams) { return CheckRcDp(CheckPressUnit(station.HiLoYest.LowPress, tagParams), tagParams, cumulus.PressDPlaces); } - private string TagTpressYl(Dictionary tagParams) + private string TagTpressYl(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoYest.LowPressTime, "HH:mm", tagParams); } - private string TaghumYh(Dictionary tagParams) + private string TaghumYh(Dictionary tagParams) { return station.HiLoYest.HighHumidity.ToString(); } - private string TagThumYh(Dictionary tagParams) + private string TagThumYh(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoYest.HighHumidityTime, "HH:mm", tagParams); } - private string TaghumYl(Dictionary tagParams) + private string TaghumYl(Dictionary tagParams) { return station.HiLoYest.LowHumidity.ToString(); } - private string TagThumYl(Dictionary tagParams) + private string TagThumYl(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoYest.LowHumidityTime, "HH:mm", tagParams); } - private string TagwindYm(Dictionary tagParams) + private string TagwindYm(Dictionary tagParams) { return CheckRcDp(CheckWindUnit(station.HiLoYest.HighWind, tagParams), tagParams, cumulus.WindAvgDPlaces); } - private string TagYbeaufort(Dictionary tagParams) + private string TagYbeaufort(Dictionary tagParams) { return "F" + station.Beaufort(station.HiLoYest.HighWind); } - private string TagYbeaufortnumber(Dictionary tagParams) + private string TagYbeaufortnumber(Dictionary tagParams) { return station.Beaufort(station.HiLoYest.HighWind).ToString(); } - private string TagYbeaudesc(Dictionary tagParams) + private string TagYbeaudesc(Dictionary tagParams) { return cumulus.BeaufortDesc(station.HiLoYest.HighWind); } - private string TagTwindYm(Dictionary tagParams) + private string TagTwindYm(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoYest.HighWindTime, "HH:mm", tagParams); } - private string TagwgustYm(Dictionary tagParams) + private string TagwgustYm(Dictionary tagParams) { return CheckRcDp(CheckWindUnit(station.HiLoYest.HighGust, tagParams), tagParams, cumulus.WindDPlaces); } - private string TagTwgustYm(Dictionary tagParams) + private string TagTwgustYm(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoYest.HighGustTime, "HH:mm", tagParams); } - private string TagbearingYm(Dictionary tagParams) + private string TagbearingYm(Dictionary tagParams) { return station.HiLoYest.HighGustBearing.ToString(); } private string TagdirectionYm(Dictionary tagParams) { - return station.CompassPoint(station.HiLoYest.HighGustBearing); + return station.CompassPoint(station.HiLoYest.HighGustBearing); } - private string TagrrateYm(Dictionary tagParams) + private string TagrrateYm(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.HiLoYest.HighRainRate, tagParams), tagParams, cumulus.RainDPlaces); } - private string TagTrrateYm(Dictionary tagParams) + private string TagTrrateYm(Dictionary tagParams) { return GetFormattedDateTime(station.HiLoYest.HighRainRateTime, "HH:mm", tagParams); } - private string TagrfallY(Dictionary tagParams) + private string TagrfallY(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.RainYesterday, tagParams), tagParams, cumulus.RainDPlaces); } // all time records - private string TagtempH(Dictionary tagParams) + private string TagtempH(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.AllTime.HighTemp.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagTtempH(Dictionary tagParams) + private string TagTtempH(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.HighTemp.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagtempL(Dictionary tagParams) + private string TagtempL(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.AllTime.LowTemp.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagTtempL(Dictionary tagParams) + private string TagTtempL(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.LowTemp.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagapptempH(Dictionary tagParams) + private string TagapptempH(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.AllTime.HighAppTemp.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagTapptempH(Dictionary tagParams) + private string TagTapptempH(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.HighAppTemp.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagapptempL(Dictionary tagParams) + private string TagapptempL(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.AllTime.LowAppTemp.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagTapptempL(Dictionary tagParams) + private string TagTapptempL(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.LowAppTemp.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } @@ -2391,92 +2391,92 @@ private string TagThumidexH(Dictionary tagParams) return GetFormattedDateTime(station.AllTime.HighHumidex.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagdewpointH(Dictionary tagParams) + private string TagdewpointH(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.AllTime.HighDewPoint.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagTdewpointH(Dictionary tagParams) + private string TagTdewpointH(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.HighDewPoint.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagdewpointL(Dictionary tagParams) + private string TagdewpointL(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.AllTime.LowDewPoint.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagTdewpointL(Dictionary tagParams) + private string TagTdewpointL(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.LowDewPoint.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagheatindexH(Dictionary tagParams) + private string TagheatindexH(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.AllTime.HighHeatIndex.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagTheatindexH(Dictionary tagParams) + private string TagTheatindexH(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.HighHeatIndex.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TaggustM(Dictionary tagParams) + private string TaggustM(Dictionary tagParams) { return CheckRcDp(CheckWindUnit(station.AllTime.HighGust.Val, tagParams), tagParams, cumulus.WindDPlaces); } - private string TagTgustM(Dictionary tagParams) + private string TagTgustM(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.HighGust.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagwspeedH(Dictionary tagParams) + private string TagwspeedH(Dictionary tagParams) { return CheckRcDp(CheckWindUnit(station.AllTime.HighWind.Val, tagParams), tagParams, cumulus.WindAvgDPlaces); } - private string TagTwspeedH(Dictionary tagParams) + private string TagTwspeedH(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.HighWind.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagwchillH(Dictionary tagParams) + private string TagwchillH(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.AllTime.LowChill.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagTwchillH(Dictionary tagParams) + private string TagTwchillH(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.LowChill.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagrrateM(Dictionary tagParams) + private string TagrrateM(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.AllTime.HighRainRate.Val, tagParams), tagParams, cumulus.RainDPlaces); } - private string TagTrrateM(Dictionary tagParams) + private string TagTrrateM(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.HighRainRate.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagwindrunH(Dictionary tagParams) + private string TagwindrunH(Dictionary tagParams) { return CheckRcDp(CheckWindRunUnit(station.AllTime.HighWindRun.Val, tagParams), tagParams, cumulus.WindRunDPlaces); } - private string TagTwindrunH(Dictionary tagParams) + private string TagTwindrunH(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.HighWindRun.Ts, "o\\n dd MMMM yyyy", tagParams); } - private string TagrfallH(Dictionary tagParams) + private string TagrfallH(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.AllTime.DailyRain.Val, tagParams), tagParams, cumulus.RainDPlaces); } - private string TagTrfallH(Dictionary tagParams) + private string TagTrfallH(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.DailyRain.Ts, "o\\n dd MMMM yyyy", tagParams); } @@ -2491,185 +2491,185 @@ private string TagTr24hourH(Dictionary tagParams) return GetFormattedDateTime(station.AllTime.HighRain24Hours.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagLongestDryPeriod(Dictionary tagParams) + private string TagLongestDryPeriod(Dictionary tagParams) { return station.AllTime.LongestDryPeriod.Val == Cumulus.DefaultHiVal ? "--" : station.AllTime.LongestDryPeriod.Val.ToString("F0"); } - private string TagTLongestDryPeriod(Dictionary tagParams) + private string TagTLongestDryPeriod(Dictionary tagParams) { return station.AllTime.LongestDryPeriod.Val == Cumulus.DefaultHiVal ? "--" : GetFormattedDateTime(station.AllTime.LongestDryPeriod.Ts, "\\to dd MMMM yyyy", tagParams); } - private string TagLongestWetPeriod(Dictionary tagParams) + private string TagLongestWetPeriod(Dictionary tagParams) { return station.AllTime.LongestWetPeriod.Val == Cumulus.DefaultHiVal ? "--" : station.AllTime.LongestWetPeriod.Val.ToString("F0"); } - private string TagTLongestWetPeriod(Dictionary tagParams) + private string TagTLongestWetPeriod(Dictionary tagParams) { return station.AllTime.LongestWetPeriod.Val == Cumulus.DefaultHiVal ? "--" : GetFormattedDateTime(station.AllTime.LongestWetPeriod.Ts, "\\to dd MMMM yyyy", tagParams); } - private string TagLowDailyTempRange(Dictionary tagParams) + private string TagLowDailyTempRange(Dictionary tagParams) { return CheckRcDp(CheckTempUnitAbs(station.AllTime.LowDailyTempRange.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagHighDailyTempRange(Dictionary tagParams) + private string TagHighDailyTempRange(Dictionary tagParams) { return CheckRcDp(CheckTempUnitAbs(station.AllTime.HighDailyTempRange.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagTLowDailyTempRange(Dictionary tagParams) + private string TagTLowDailyTempRange(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.LowDailyTempRange.Ts, "o\\n dd MMMM yyyy", tagParams); } - private string TagTHighDailyTempRange(Dictionary tagParams) + private string TagTHighDailyTempRange(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.HighDailyTempRange.Ts, "o\\n dd MMMM yyyy", tagParams); } - private string TagrfallhH(Dictionary tagParams) + private string TagrfallhH(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.AllTime.HourlyRain.Val, tagParams), tagParams, cumulus.RainDPlaces); } - private string TagTrfallhH(Dictionary tagParams) + private string TagTrfallhH(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.HourlyRain.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagrfallmH(Dictionary tagParams) + private string TagrfallmH(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.AllTime.MonthlyRain.Val, tagParams), tagParams, cumulus.RainDPlaces); } - private string TagTrfallmH(Dictionary tagParams) + private string TagTrfallmH(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.MonthlyRain.Ts, "MMMM yyyy", tagParams); } - private string TagpressH(Dictionary tagParams) + private string TagpressH(Dictionary tagParams) { return CheckRcDp(CheckPressUnit(station.AllTime.HighPress.Val, tagParams), tagParams, cumulus.PressDPlaces); } - private string TagTpressH(Dictionary tagParams) + private string TagTpressH(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.HighPress.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagpressL(Dictionary tagParams) + private string TagpressL(Dictionary tagParams) { return CheckRcDp(CheckPressUnit(station.AllTime.LowPress.Val, tagParams), tagParams, cumulus.PressDPlaces); } - private string TagTpressL(Dictionary tagParams) + private string TagTpressL(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.LowPress.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TaghumH(Dictionary tagParams) + private string TaghumH(Dictionary tagParams) { return station.AllTime.HighHumidity.Val.ToString(cumulus.HumFormat); } - private string TagThumH(Dictionary tagParams) + private string TagThumH(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.HighHumidity.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TaghumL(Dictionary tagParams) + private string TaghumL(Dictionary tagParams) { return station.AllTime.LowHumidity.Val.ToString(cumulus.HumFormat); } - private string TagThumL(Dictionary tagParams) + private string TagThumL(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.LowHumidity.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string Tagrecordsbegandate(Dictionary tagParams) + private string Tagrecordsbegandate(Dictionary tagParams) { return GetFormattedDateTime(cumulus.RecordsBeganDateTime, "dd MMMM yyyy", tagParams); } - private string TagDaysSinceRecordsBegan(Dictionary tagParams) + private string TagDaysSinceRecordsBegan(Dictionary tagParams) { return (DateTime.Now - cumulus.RecordsBeganDateTime).Days.ToString(); } - private string TagmintempH(Dictionary tagParams) + private string TagmintempH(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.AllTime.HighMinTemp.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagTmintempH(Dictionary tagParams) + private string TagTmintempH(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.HighMinTemp.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagmaxtempL(Dictionary tagParams) + private string TagmaxtempL(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.AllTime.LowMaxTemp.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagTmaxtempL(Dictionary tagParams) + private string TagTmaxtempL(Dictionary tagParams) { return GetFormattedDateTime(station.AllTime.LowMaxTemp.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } // end of all-time records // month by month all time records - private string TagByMonthTempH(Dictionary tagParams) + private string TagByMonthTempH(Dictionary tagParams) { var month = GetMonthParam(tagParams); var rec = station.MonthlyRecs[month].HighTemp; return rec.Ts <= cumulus.defaultRecordTS ? "---" : CheckRcDp(CheckTempUnit(rec.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagByMonthTempHt(Dictionary tagParams) + private string TagByMonthTempHt(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].HighTemp.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagByMonthTempL(Dictionary tagParams) + private string TagByMonthTempL(Dictionary tagParams) { var month = GetMonthParam(tagParams); var rec = station.MonthlyRecs[month].LowTemp; return rec.Ts <= cumulus.defaultRecordTS ? "---" : CheckRcDp(CheckTempUnit(rec.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagByMonthTempLt(Dictionary tagParams) + private string TagByMonthTempLt(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].LowTemp.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagByMonthAppTempH(Dictionary tagParams) + private string TagByMonthAppTempH(Dictionary tagParams) { var month = GetMonthParam(tagParams); var rec = station.MonthlyRecs[month].HighAppTemp; return rec.Ts <= cumulus.defaultRecordTS ? "---" : CheckRcDp(CheckTempUnit(rec.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagByMonthAppTempHt(Dictionary tagParams) + private string TagByMonthAppTempHt(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].HighAppTemp.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagByMonthAppTempL(Dictionary tagParams) + private string TagByMonthAppTempL(Dictionary tagParams) { var month = GetMonthParam(tagParams); var rec = station.MonthlyRecs[month].LowAppTemp; return rec.Ts <= cumulus.defaultRecordTS ? "---" : CheckRcDp(CheckTempUnit(rec.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagByMonthAppTempLt(Dictionary tagParams) + private string TagByMonthAppTempLt(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].LowAppTemp.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); @@ -2713,118 +2713,118 @@ private string TagByMonthHumidexHt(Dictionary tagParams) return GetFormattedDateTime(station.MonthlyRecs[month].HighHumidex.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagByMonthDewPointH(Dictionary tagParams) + private string TagByMonthDewPointH(Dictionary tagParams) { var month = GetMonthParam(tagParams); var rec = station.MonthlyRecs[month].HighDewPoint; return rec.Ts <= cumulus.defaultRecordTS ? "---" : CheckRcDp(CheckTempUnit(rec.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagByMonthDewPointHt(Dictionary tagParams) + private string TagByMonthDewPointHt(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].HighDewPoint.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagByMonthDewPointL(Dictionary tagParams) + private string TagByMonthDewPointL(Dictionary tagParams) { var month = GetMonthParam(tagParams); var rec = station.MonthlyRecs[month].LowDewPoint; return rec.Ts <= cumulus.defaultRecordTS ? "---" : CheckRcDp(CheckTempUnit(rec.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagByMonthDewPointLt(Dictionary tagParams) + private string TagByMonthDewPointLt(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].LowDewPoint.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagByMonthHeatIndexH(Dictionary tagParams) + private string TagByMonthHeatIndexH(Dictionary tagParams) { var month = GetMonthParam(tagParams); var rec = station.MonthlyRecs[month].HighHeatIndex; return rec.Ts <= cumulus.defaultRecordTS ? "---" : CheckRcDp(CheckTempUnit(rec.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagByMonthHeatIndexHt(Dictionary tagParams) + private string TagByMonthHeatIndexHt(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].HighHeatIndex.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagByMonthGustH(Dictionary tagParams) + private string TagByMonthGustH(Dictionary tagParams) { var month = GetMonthParam(tagParams); var rec = station.MonthlyRecs[month].HighGust; return rec.Ts <= cumulus.defaultRecordTS ? "---" : CheckRcDp(CheckWindUnit(rec.Val, tagParams), tagParams, cumulus.WindDPlaces); } - private string TagByMonthGustHt(Dictionary tagParams) + private string TagByMonthGustHt(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].HighGust.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagByMonthWindH(Dictionary tagParams) + private string TagByMonthWindH(Dictionary tagParams) { var month = GetMonthParam(tagParams); var rec = station.MonthlyRecs[month].HighWind; return rec.Ts <= cumulus.defaultRecordTS ? "---" : CheckRcDp(CheckWindUnit(rec.Val, tagParams), tagParams, cumulus.WindDPlaces); } - private string TagByMonthWindHt(Dictionary tagParams) + private string TagByMonthWindHt(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].HighWind.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagByMonthWChillL(Dictionary tagParams) + private string TagByMonthWChillL(Dictionary tagParams) { var month = GetMonthParam(tagParams); var rec = station.MonthlyRecs[month].LowChill; return rec.Ts <= cumulus.defaultRecordTS ? "---" : CheckRcDp(CheckTempUnit(rec.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagByMonthWChillLt(Dictionary tagParams) + private string TagByMonthWChillLt(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].LowChill.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagByMonthRainRateH(Dictionary tagParams) + private string TagByMonthRainRateH(Dictionary tagParams) { var month = GetMonthParam(tagParams); var rec = station.MonthlyRecs[month].HighRainRate; return rec.Ts <= cumulus.defaultRecordTS ? "---" : CheckRcDp(CheckRainUnit(rec.Val, tagParams), tagParams, cumulus.RainDPlaces); } - private string TagByMonthRainRateHt(Dictionary tagParams) + private string TagByMonthRainRateHt(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].HighRainRate.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagByMonthWindRunH(Dictionary tagParams) + private string TagByMonthWindRunH(Dictionary tagParams) { var month = GetMonthParam(tagParams); var rec = station.MonthlyRecs[month].HighWindRun; return rec.Ts <= cumulus.defaultRecordTS ? "---" : CheckRcDp(CheckWindRunUnit(rec.Val, tagParams), tagParams, cumulus.WindRunDPlaces); } - private string TagByMonthWindRunHt(Dictionary tagParams) + private string TagByMonthWindRunHt(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].HighWindRun.Ts, "o\\n dd MMMM yyyy", tagParams); } - private string TagByMonthDailyRainH(Dictionary tagParams) + private string TagByMonthDailyRainH(Dictionary tagParams) { var month = GetMonthParam(tagParams); var rec = station.MonthlyRecs[month].DailyRain; return rec.Ts <= cumulus.defaultRecordTS ? "---" : CheckRcDp(CheckRainUnit(rec.Val, tagParams), tagParams, cumulus.RainDPlaces); } - private string TagByMonthDailyRainHt(Dictionary tagParams) + private string TagByMonthDailyRainHt(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].DailyRain.Ts, "o\\n dd MMMM yyyy", tagParams); @@ -2843,153 +2843,153 @@ private string TagByMonthRain24HourHt(Dictionary tagParams) return GetFormattedDateTime(station.MonthlyRecs[month].HighRain24Hours.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagByMonthLongestDryPeriod(Dictionary tagParams) + private string TagByMonthLongestDryPeriod(Dictionary tagParams) { var month = GetMonthParam(tagParams); return station.MonthlyRecs[month].LongestDryPeriod.Val == Cumulus.DefaultHiVal ? "--" : GetMonthlyAlltimeValueStr(station.MonthlyRecs[month].LongestDryPeriod, tagParams, 0); } - private string TagByMonthLongestDryPeriodT(Dictionary tagParams) + private string TagByMonthLongestDryPeriodT(Dictionary tagParams) { var month = GetMonthParam(tagParams); return station.MonthlyRecs[month].LongestDryPeriod.Val == Cumulus.DefaultHiVal ? "--" : GetFormattedDateTime(station.MonthlyRecs[month].LongestDryPeriod.Ts, "\\to dd MMMM yyyy", tagParams); } - private string TagByMonthLongestWetPeriod(Dictionary tagParams) + private string TagByMonthLongestWetPeriod(Dictionary tagParams) { var month = GetMonthParam(tagParams); return station.MonthlyRecs[month].LongestWetPeriod.Val == Cumulus.DefaultHiVal ? "--" : GetMonthlyAlltimeValueStr(station.MonthlyRecs[month].LongestWetPeriod, tagParams, 0); } - private string TagByMonthLongestWetPeriodT(Dictionary tagParams) + private string TagByMonthLongestWetPeriodT(Dictionary tagParams) { var month = GetMonthParam(tagParams); return station.MonthlyRecs[month].LongestWetPeriod.Val == Cumulus.DefaultHiVal ? "--" : GetFormattedDateTime(station.MonthlyRecs[month].LongestWetPeriod.Ts, "\\to dd MMMM yyyy", tagParams); } - private string TagByMonthLowDailyTempRange(Dictionary tagParams) + private string TagByMonthLowDailyTempRange(Dictionary tagParams) { var month = GetMonthParam(tagParams); var rec = station.MonthlyRecs[month].LowDailyTempRange; return rec.Ts <= cumulus.defaultRecordTS ? "---" : CheckRcDp(CheckTempUnitAbs(rec.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagByMonthHighDailyTempRange(Dictionary tagParams) + private string TagByMonthHighDailyTempRange(Dictionary tagParams) { var month = GetMonthParam(tagParams); var rec = station.MonthlyRecs[month].HighDailyTempRange; return rec.Ts <= cumulus.defaultRecordTS ? "---" : CheckRcDp(CheckTempUnitAbs(rec.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagByMonthLowDailyTempRangeT(Dictionary tagParams) + private string TagByMonthLowDailyTempRangeT(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].LowDailyTempRange.Ts, "o\\n dd MMMM yyyy", tagParams); } - private string TagByMonthHighDailyTempRangeT(Dictionary tagParams) + private string TagByMonthHighDailyTempRangeT(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].HighDailyTempRange.Ts, "o\\n dd MMMM yyyy", tagParams); } - private string TagByMonthHourlyRainH(Dictionary tagParams) + private string TagByMonthHourlyRainH(Dictionary tagParams) { var month = GetMonthParam(tagParams); var rec = station.MonthlyRecs[month].HourlyRain; return rec.Ts <= cumulus.defaultRecordTS ? "---" : CheckRcDp(CheckRainUnit(rec.Val, tagParams), tagParams, cumulus.RainDPlaces); } - private string TagByMonthHourlyRainHt(Dictionary tagParams) + private string TagByMonthHourlyRainHt(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].HourlyRain.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagByMonthMonthlyRainH(Dictionary tagParams) + private string TagByMonthMonthlyRainH(Dictionary tagParams) { var month = GetMonthParam(tagParams); var rec = station.MonthlyRecs[month].MonthlyRain; return rec.Ts <= cumulus.defaultRecordTS ? "---" : CheckRcDp(CheckRainUnit(rec.Val, tagParams), tagParams, cumulus.RainDPlaces); } - private string TagByMonthMonthlyRainHt(Dictionary tagParams) + private string TagByMonthMonthlyRainHt(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].MonthlyRain.Ts, "MMMM yyyy", tagParams); } - private string TagByMonthPressH(Dictionary tagParams) + private string TagByMonthPressH(Dictionary tagParams) { var month = GetMonthParam(tagParams); var rec = station.MonthlyRecs[month].HighPress; return rec.Ts <= cumulus.defaultRecordTS ? "---" : CheckRcDp(CheckPressUnit(rec.Val, tagParams), tagParams, cumulus.PressDPlaces); } - private string TagByMonthPressHt(Dictionary tagParams) + private string TagByMonthPressHt(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].HighPress.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagByMonthPressL(Dictionary tagParams) + private string TagByMonthPressL(Dictionary tagParams) { var month = GetMonthParam(tagParams); var rec = station.MonthlyRecs[month].LowPress; return rec.Ts <= cumulus.defaultRecordTS ? "---" : CheckRcDp(CheckPressUnit(rec.Val, tagParams), tagParams, cumulus.PressDPlaces); } - private string TagByMonthPressLt(Dictionary tagParams) + private string TagByMonthPressLt(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].LowPress.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagByMonthHumH(Dictionary tagParams) + private string TagByMonthHumH(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetMonthlyAlltimeValueStr(station.MonthlyRecs[month].HighHumidity, tagParams, cumulus.HumDPlaces); } - private string TagByMonthHumHt(Dictionary tagParams) + private string TagByMonthHumHt(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].HighHumidity.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagByMonthHumL(Dictionary tagParams) + private string TagByMonthHumL(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetMonthlyAlltimeValueStr(station.MonthlyRecs[month].LowHumidity, tagParams, cumulus.HumDPlaces); } - private string TagByMonthHumLt(Dictionary tagParams) + private string TagByMonthHumLt(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].LowHumidity.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagByMonthMinTempH(Dictionary tagParams) + private string TagByMonthMinTempH(Dictionary tagParams) { var month = GetMonthParam(tagParams); var rec = station.MonthlyRecs[month].HighMinTemp; return rec.Ts <= cumulus.defaultRecordTS ? "---" : CheckRcDp(CheckTempUnit(rec.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagByMonthMinTempHt(Dictionary tagParams) + private string TagByMonthMinTempHt(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].HighMinTemp.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); } - private string TagByMonthMaxTempL(Dictionary tagParams) + private string TagByMonthMaxTempL(Dictionary tagParams) { var month = GetMonthParam(tagParams); var rec = station.MonthlyRecs[month].LowMaxTemp; return rec.Ts <= cumulus.defaultRecordTS ? "---" : CheckRcDp(CheckTempUnit(rec.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagByMonthMaxTempLt(Dictionary tagParams) + private string TagByMonthMaxTempLt(Dictionary tagParams) { var month = GetMonthParam(tagParams); return GetFormattedDateTime(station.MonthlyRecs[month].LowMaxTemp.Ts, "\\a\\t HH:mm o\\n dd MMMM yyyy", tagParams); @@ -2997,12 +2997,12 @@ private string TagByMonthMaxTempLt(Dictionary tagParams) // end of month-by-month all-time records - private string Taggraphperiod(Dictionary tagParams) + private string Taggraphperiod(Dictionary tagParams) { return cumulus.GraphHours.ToString(); } - private string Tagstationtype(Dictionary tagParams) + private string Tagstationtype(Dictionary tagParams) { if (cumulus.StationModel != string.Empty) { @@ -3022,7 +3022,7 @@ private string TagstationtypeJsEnc(Dictionary tagParams) return cumulus.StationType == -1 ? "undefined" : EncodeForJs(cumulus.StationDesc[cumulus.StationType]); } - private string Taglatitude(Dictionary tagParams) + private string Taglatitude(Dictionary tagParams) { var dpstr = tagParams.Get("dp"); if (dpstr == null) @@ -3058,7 +3058,7 @@ private string TaglatitudeJsEnc(Dictionary tagParams) } } - private string Taglongitude(Dictionary tagParams) + private string Taglongitude(Dictionary tagParams) { var dpstr = tagParams.Get("dp"); if (dpstr == null) @@ -3082,7 +3082,7 @@ private string TaglongitudeJsEnc(Dictionary tagParams) return EncodeForJs(cumulus.LonTxt); } - private string Taglocation(Dictionary tagParams) + private string Taglocation(Dictionary tagParams) { return cumulus.LocationName; } @@ -3098,7 +3098,7 @@ private string TaglocationJsEnc(Dictionary tagParams) } - private string Taglonglocation(Dictionary tagParams) + private string Taglonglocation(Dictionary tagParams) { return cumulus.LocationDesc; } @@ -3113,74 +3113,74 @@ private string TaglonglocationJsEnc(Dictionary tagParams) return EncodeForJs(cumulus.LocationDesc); } - private string Tagsunrise(Dictionary tagParams) + private string Tagsunrise(Dictionary tagParams) { return GetFormattedDateTime(SunriseSunset.RoundToMinute(cumulus.SunRiseTime), "HH:mm", tagParams); } - private string Tagsunset(Dictionary tagParams) + private string Tagsunset(Dictionary tagParams) { return GetFormattedDateTime(SunriseSunset.RoundToMinute(cumulus.SunSetTime), "HH:mm", tagParams); } - private string Tagdaylength(Dictionary tagParams) + private string Tagdaylength(Dictionary tagParams) { return GetFormattedDateTime(cumulus.DayLength, "HH:mm", tagParams); } - private string Tagdawn(Dictionary tagParams) + private string Tagdawn(Dictionary tagParams) { return GetFormattedDateTime(SunriseSunset.RoundToMinute(cumulus.Dawn), "HH:mm", tagParams); } - private string Tagdusk(Dictionary tagParams) + private string Tagdusk(Dictionary tagParams) { return GetFormattedDateTime(SunriseSunset.RoundToMinute(cumulus.Dusk), "HH:mm", tagParams); } - private string Tagdaylightlength(Dictionary tagParams) + private string Tagdaylightlength(Dictionary tagParams) { return GetFormattedDateTime(cumulus.DaylightLength, "HH:mm", tagParams); } - private string Tagisdaylight(Dictionary tagParams) + private string Tagisdaylight(Dictionary tagParams) { return cumulus.IsDaylight() ? "1" : "0"; } - private string TagIsSunUp(Dictionary tagParams) + private string TagIsSunUp(Dictionary tagParams) { return cumulus.IsSunUp() ? "1" : "0"; } - private string TagSensorContactLost(Dictionary tagParams) + private string TagSensorContactLost(Dictionary tagParams) { return station.SensorContactLost ? "1" : "0"; } - private string TagDataStopped(Dictionary tagParams) + private string TagDataStopped(Dictionary tagParams) { return cumulus.DataStoppedAlarm.Triggered ? "1" : "0"; } - private string Tagmoonrise(Dictionary tagParams) + private string Tagmoonrise(Dictionary tagParams) { return cumulus.MoonRiseTime.Hours < 0 ? "-----" : GetFormattedDateTime(DateTime.Now.Date.AddSeconds(cumulus.MoonRiseTime.TotalSeconds), "HH:mm", tagParams); } - private string Tagmoonset(Dictionary tagParams) + private string Tagmoonset(Dictionary tagParams) { return cumulus.MoonSetTime.Hours < 0 ? "-----" : GetFormattedDateTime(DateTime.Now.Date.AddSeconds(cumulus.MoonSetTime.TotalSeconds), "HH:mm", tagParams); } - private string Tagmoonphase(Dictionary tagParams) + private string Tagmoonphase(Dictionary tagParams) { return cumulus.MoonPhaseString; } - private string Tagaltitude(Dictionary tagParams) + private string Tagaltitude(Dictionary tagParams) { - return cumulus.Altitude + (cumulus.AltitudeInFeet ? " ft" :" m"); + return cumulus.Altitude + (cumulus.AltitudeInFeet ? " ft" : " m"); } private string Tagaltitudenoenc(Dictionary tagParams) @@ -3188,7 +3188,7 @@ private string Tagaltitudenoenc(Dictionary tagParams) return cumulus.Altitude + (cumulus.AltitudeInFeet ? " ft" : " m"); } - private string Tagforum(Dictionary tagParams) + private string Tagforum(Dictionary tagParams) { if (string.IsNullOrEmpty(cumulus.ForumURL)) { @@ -3208,7 +3208,7 @@ private string Tagforumurl(Dictionary tagParams) return cumulus.ForumURL; } - private string Tagwebcam(Dictionary tagParams) + private string Tagwebcam(Dictionary tagParams) { if (string.IsNullOrEmpty(cumulus.WebcamURL)) { @@ -3228,7 +3228,7 @@ private string Tagwebcamurl(Dictionary tagParams) } - private string Tagtempunit(Dictionary tagParams) + private string Tagtempunit(Dictionary tagParams) { return EncodeForWeb(cumulus.Units.TempText); } @@ -3238,47 +3238,47 @@ private string Tagtempunitnoenc(Dictionary tagParams) return cumulus.Units.TempText; } - private string Tagtempunitnodeg(Dictionary tagParams) + private string Tagtempunitnodeg(Dictionary tagParams) { - return cumulus.Units.TempText.Substring(1,1); + return cumulus.Units.TempText.Substring(1, 1); } - private string Tagwindunit(Dictionary tagParams) + private string Tagwindunit(Dictionary tagParams) { return cumulus.Units.WindText; } - private string Tagwindrununit(Dictionary tagParams) + private string Tagwindrununit(Dictionary tagParams) { return cumulus.Units.WindRunText; } - private string Tagpressunit(Dictionary tagParams) + private string Tagpressunit(Dictionary tagParams) { return cumulus.Units.PressText; } - private string Tagrainunit(Dictionary tagParams) + private string Tagrainunit(Dictionary tagParams) { return cumulus.Units.RainText; } - private string Taginterval(Dictionary tagParams) + private string Taginterval(Dictionary tagParams) { return cumulus.UpdateInterval.ToString(); } - private string Tagrealtimeinterval(Dictionary tagParams) + private string Tagrealtimeinterval(Dictionary tagParams) { - return (cumulus.RealtimeInterval/1000).ToString(); + return (cumulus.RealtimeInterval / 1000).ToString(); } - private string Tagversion(Dictionary tagParams) + private string Tagversion(Dictionary tagParams) { return cumulus.Version; } - private string Tagbuild(Dictionary tagParams) + private string Tagbuild(Dictionary tagParams) { return cumulus.Build; } @@ -3300,41 +3300,41 @@ private string TagNewBuildNumber(Dictionary tagParams) return cumulus.LatestBuild; } - private static string Tagupdate(Dictionary tagParams) + private static string Tagupdate(Dictionary tagParams) { string dtformat = tagParams.Get("format"); return dtformat == null ? DateTime.Now.ToString() : DateTime.Now.ToString(dtformat); } - private string TagLatestNoaaMonthlyReport(Dictionary tagParams) + private string TagLatestNoaaMonthlyReport(Dictionary tagParams) { return cumulus.NOAAconf.LatestMonthReport; } - private string TagLatestNoaaYearlyReport(Dictionary tagParams) + private string TagLatestNoaaYearlyReport(Dictionary tagParams) { return cumulus.NOAAconf.LatestYearReport; } - private string TagMoonPercent(Dictionary tagParams) + private string TagMoonPercent(Dictionary tagParams) { return CheckRcDp(cumulus.MoonPercent, tagParams, 0); } - private string TagMoonPercentAbs(Dictionary tagParams) + private string TagMoonPercentAbs(Dictionary tagParams) { return CheckRcDp(Math.Abs(cumulus.MoonPercent), tagParams, 0); } - private string TagMoonAge(Dictionary tagParams) + private string TagMoonAge(Dictionary tagParams) { var tcstr = tagParams.Get("tc"); return tcstr == "y" ? Math.Truncate(cumulus.MoonAge).ToString() : CheckRcDp(cumulus.MoonAge, tagParams, 0); } - private string TagLastRainTipIso(Dictionary tagParams) + private string TagLastRainTipIso(Dictionary tagParams) { return station.LastRainTip; } @@ -3353,7 +3353,7 @@ private string TagLastRainTip(Dictionary tagParams) } } - private string TagMinutesSinceLastRainTip(Dictionary tagParams) + private string TagMinutesSinceLastRainTip(Dictionary tagParams) { DateTime lastTip; try @@ -3368,17 +3368,17 @@ private string TagMinutesSinceLastRainTip(Dictionary tagParams) return ((int) (DateTime.Now - lastTip).TotalMinutes).ToString(); } - private string TagRCtemp(Dictionary tagParams) + private string TagRCtemp(Dictionary tagParams) { return ReplaceCommas(Tagtemp(tagParams)); } - private string TagRCtempTh(Dictionary tagParams) + private string TagRCtempTh(Dictionary tagParams) { return ReplaceCommas(TagtempTh(tagParams)); } - private string TagRCtempTl(Dictionary tagParams) + private string TagRCtempTl(Dictionary tagParams) { return ReplaceCommas(TagtempTl(tagParams)); } @@ -3388,82 +3388,82 @@ private string TagRCintemp(Dictionary tagParams) return ReplaceCommas(Tagintemp(tagParams)); } - private string TagRCdew(Dictionary tagParams) + private string TagRCdew(Dictionary tagParams) { return ReplaceCommas(Tagdew(tagParams)); } - private string TagRCheatindex(Dictionary tagParams) + private string TagRCheatindex(Dictionary tagParams) { return ReplaceCommas(Tagheatindex(tagParams)); } - private string TagRCwchill(Dictionary tagParams) + private string TagRCwchill(Dictionary tagParams) { return ReplaceCommas(Tagwchill(tagParams)); } - private string TagRChum(Dictionary tagParams) + private string TagRChum(Dictionary tagParams) { return ReplaceCommas(Taghum(tagParams)); } - private string TagRCinhum(Dictionary tagParams) + private string TagRCinhum(Dictionary tagParams) { return ReplaceCommas(Taginhum(tagParams)); } - private string TagRCrfall(Dictionary tagParams) + private string TagRCrfall(Dictionary tagParams) { return ReplaceCommas(Tagrfall(tagParams)); } - private string TagRCrrate(Dictionary tagParams) + private string TagRCrrate(Dictionary tagParams) { return ReplaceCommas(Tagrrate(tagParams)); } - private string TagRCrrateTm(Dictionary tagParams) + private string TagRCrrateTm(Dictionary tagParams) { return ReplaceCommas(TagrrateTm(tagParams)); } - private string TagRCwlatest(Dictionary tagParams) + private string TagRCwlatest(Dictionary tagParams) { return ReplaceCommas(Tagwlatest(tagParams)); } - private string TagRCwgust(Dictionary tagParams) + private string TagRCwgust(Dictionary tagParams) { return ReplaceCommas(Tagwgust(tagParams)); } - private string TagRCwspeed(Dictionary tagParams) + private string TagRCwspeed(Dictionary tagParams) { return ReplaceCommas(Tagwspeed(tagParams)); } - private string TagRCwgustTm(Dictionary tagParams) + private string TagRCwgustTm(Dictionary tagParams) { return ReplaceCommas(TagwgustTm(tagParams)); } - private string TagRCpress(Dictionary tagParams) + private string TagRCpress(Dictionary tagParams) { return ReplaceCommas(Tagpress(tagParams)); } - private string TagRCpressTh(Dictionary tagParams) + private string TagRCpressTh(Dictionary tagParams) { return ReplaceCommas(TagpressTh(tagParams)); } - private string TagRCpressTl(Dictionary tagParams) + private string TagRCpressTl(Dictionary tagParams) { return ReplaceCommas(TagpressTl(tagParams)); } - private string TagEt(Dictionary tagParams) + private string TagEt(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.ET, tagParams), tagParams, cumulus.RainDPlaces + 1); } @@ -3473,27 +3473,27 @@ private string TagAnnualEt(Dictionary tagParams) return CheckRcDp(CheckRainUnit(station.AnnualETTotal, tagParams), tagParams, cumulus.RainDPlaces + 1); } - private string TagLight(Dictionary tagParams) + private string TagLight(Dictionary tagParams) { return CheckRcDp(station.LightValue, tagParams, 1); } - private string TagUv(Dictionary tagParams) + private string TagUv(Dictionary tagParams) { return CheckRcDp(station.UV, tagParams, cumulus.UVDPlaces); } - private string TagSolarRad(Dictionary tagParams) + private string TagSolarRad(Dictionary tagParams) { return station.SolarRad.ToString(); } - private string TagCurrentSolarMax(Dictionary tagParams) + private string TagCurrentSolarMax(Dictionary tagParams) { return station.CurrentSolarMax.ToString(); } - private string TagSunshineHours(Dictionary tagParams) + private string TagSunshineHours(Dictionary tagParams) { return CheckRcDp(station.SunshineHours, tagParams, cumulus.SunshineDPlaces); } @@ -3554,17 +3554,17 @@ private string TagSunshineHoursYear(Dictionary tagParams) } - private string TagThwIndex(Dictionary tagParams) + private string TagThwIndex(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.THWIndex, tagParams), tagParams, 1); } - private string TagThswIndex(Dictionary tagParams) + private string TagThswIndex(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.THSWIndex, tagParams), tagParams, 1); } - private string TagChillHours(Dictionary tagParams) + private string TagChillHours(Dictionary tagParams) { return CheckRcDp(station.ChillHours, tagParams, 1); } @@ -3610,203 +3610,203 @@ private string TagYChillHours(Dictionary tagParams) return CheckRcDp(station.YestChillHours, tagParams, 1); } - private string TagYSunshineHours(Dictionary tagParams) + private string TagYSunshineHours(Dictionary tagParams) { return CheckRcDp(station.YestSunshineHours, tagParams, cumulus.SunshineDPlaces); } - private string TagIsSunny(Dictionary tagParams) + private string TagIsSunny(Dictionary tagParams) { return station.IsSunny ? "1" : "0"; } - private string TagIsFreezing(Dictionary tagParams) + private string TagIsFreezing(Dictionary tagParams) { - return station.ConvertUserTempToC(station.OutdoorTemperature)<0.09 ? "1" : "0"; + return station.ConvertUserTempToC(station.OutdoorTemperature) < 0.09 ? "1" : "0"; } - private string TagIsRaining(Dictionary tagParams) + private string TagIsRaining(Dictionary tagParams) { return station.IsRaining ? "1" : "0"; } - private string TagConsecutiveRainDays(Dictionary tagParams) + private string TagConsecutiveRainDays(Dictionary tagParams) { return station.ConsecutiveRainDays.ToString(); } - private string TagConsecutiveDryDays(Dictionary tagParams) + private string TagConsecutiveDryDays(Dictionary tagParams) { return station.ConsecutiveDryDays.ToString(); } // Extra sensors - private string TagExtraTemp1(Dictionary tagParams) + private string TagExtraTemp1(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ExtraTemp[1], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagExtraTemp2(Dictionary tagParams) + private string TagExtraTemp2(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ExtraTemp[2], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagExtraTemp3(Dictionary tagParams) + private string TagExtraTemp3(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ExtraTemp[3], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagExtraTemp4(Dictionary tagParams) + private string TagExtraTemp4(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ExtraTemp[4], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagExtraTemp5(Dictionary tagParams) + private string TagExtraTemp5(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ExtraTemp[5], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagExtraTemp6(Dictionary tagParams) + private string TagExtraTemp6(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ExtraTemp[6], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagExtraTemp7(Dictionary tagParams) + private string TagExtraTemp7(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ExtraTemp[7], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagExtraTemp8(Dictionary tagParams) + private string TagExtraTemp8(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ExtraTemp[8], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagExtraTemp9(Dictionary tagParams) + private string TagExtraTemp9(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ExtraTemp[9], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagExtraTemp10(Dictionary tagParams) + private string TagExtraTemp10(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ExtraTemp[10], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagExtraDp1(Dictionary tagParams) + private string TagExtraDp1(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ExtraDewPoint[1], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagExtraDp2(Dictionary tagParams) + private string TagExtraDp2(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ExtraDewPoint[2], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagExtraDp3(Dictionary tagParams) + private string TagExtraDp3(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ExtraDewPoint[3], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagExtraDp4(Dictionary tagParams) + private string TagExtraDp4(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ExtraDewPoint[4], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagExtraDp5(Dictionary tagParams) + private string TagExtraDp5(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ExtraDewPoint[5], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagExtraDp6(Dictionary tagParams) + private string TagExtraDp6(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ExtraDewPoint[6], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagExtraDp7(Dictionary tagParams) + private string TagExtraDp7(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ExtraDewPoint[7], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagExtraDp8(Dictionary tagParams) + private string TagExtraDp8(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ExtraDewPoint[8], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagExtraDp9(Dictionary tagParams) + private string TagExtraDp9(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ExtraDewPoint[9], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagExtraDp10(Dictionary tagParams) + private string TagExtraDp10(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ExtraDewPoint[10], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagExtraHum1(Dictionary tagParams) + private string TagExtraHum1(Dictionary tagParams) { return CheckRcDp(station.ExtraHum[1], tagParams, cumulus.HumDPlaces); } - private string TagExtraHum2(Dictionary tagParams) + private string TagExtraHum2(Dictionary tagParams) { return CheckRcDp(station.ExtraHum[2], tagParams, cumulus.HumDPlaces); } - private string TagExtraHum3(Dictionary tagParams) + private string TagExtraHum3(Dictionary tagParams) { return CheckRcDp(station.ExtraHum[3], tagParams, cumulus.HumDPlaces); } - private string TagExtraHum4(Dictionary tagParams) + private string TagExtraHum4(Dictionary tagParams) { return CheckRcDp(station.ExtraHum[4], tagParams, cumulus.HumDPlaces); } - private string TagExtraHum5(Dictionary tagParams) + private string TagExtraHum5(Dictionary tagParams) { return CheckRcDp(station.ExtraHum[5], tagParams, cumulus.HumDPlaces); } - private string TagExtraHum6(Dictionary tagParams) + private string TagExtraHum6(Dictionary tagParams) { return CheckRcDp(station.ExtraHum[6], tagParams, cumulus.HumDPlaces); } - private string TagExtraHum7(Dictionary tagParams) + private string TagExtraHum7(Dictionary tagParams) { return CheckRcDp(station.ExtraHum[7], tagParams, cumulus.HumDPlaces); } - private string TagExtraHum8(Dictionary tagParams) + private string TagExtraHum8(Dictionary tagParams) { return CheckRcDp(station.ExtraHum[8], tagParams, cumulus.HumDPlaces); } - private string TagExtraHum9(Dictionary tagParams) + private string TagExtraHum9(Dictionary tagParams) { return CheckRcDp(station.ExtraHum[9], tagParams, cumulus.HumDPlaces); } - private string TagExtraHum10(Dictionary tagParams) + private string TagExtraHum10(Dictionary tagParams) { return CheckRcDp(station.ExtraHum[10], tagParams, cumulus.HumDPlaces); } - private string TagSoilTemp1(Dictionary tagParams) + private string TagSoilTemp1(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.SoilTemp[1], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagSoilTemp2(Dictionary tagParams) + private string TagSoilTemp2(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.SoilTemp[2], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagSoilTemp3(Dictionary tagParams) + private string TagSoilTemp3(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.SoilTemp[3], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagSoilTemp4(Dictionary tagParams) + private string TagSoilTemp4(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.SoilTemp[4], tagParams), tagParams, cumulus.TempDPlaces); } @@ -3871,22 +3871,22 @@ private string TagSoilTemp16(Dictionary tagParams) return CheckRcDp(CheckTempUnit(station.SoilTemp[16], tagParams), tagParams, cumulus.TempDPlaces); } - private string TagSoilMoisture1(Dictionary tagParams) + private string TagSoilMoisture1(Dictionary tagParams) { return station.SoilMoisture1.ToString(); } - private string TagSoilMoisture2(Dictionary tagParams) + private string TagSoilMoisture2(Dictionary tagParams) { return station.SoilMoisture2.ToString(); } - private string TagSoilMoisture3(Dictionary tagParams) + private string TagSoilMoisture3(Dictionary tagParams) { return station.SoilMoisture3.ToString(); } - private string TagSoilMoisture4(Dictionary tagParams) + private string TagSoilMoisture4(Dictionary tagParams) { return station.SoilMoisture4.ToString(); } @@ -4106,12 +4106,12 @@ private string TagLightningStrikesToday(Dictionary tagParams) return station.LightningStrikesToday.ToString(); } - private string TagLeafWetness1(Dictionary tagParams) + private string TagLeafWetness1(Dictionary tagParams) { return CheckRcDp(station.LeafWetness1, tagParams, 1); } - private string TagLeafWetness2(Dictionary tagParams) + private string TagLeafWetness2(Dictionary tagParams) { return CheckRcDp(station.LeafWetness2, tagParams, 1); } @@ -4158,7 +4158,7 @@ private string TagLowTempAlarm(Dictionary tagParams) return "0"; } - private string TagHighTempAlarm(Dictionary tagParams) + private string TagHighTempAlarm(Dictionary tagParams) { if (cumulus.HighTempAlarm.Enabled) { @@ -4168,7 +4168,7 @@ private string TagHighTempAlarm(Dictionary tagParams) return "0"; } - private string TagTempChangeUpAlarm(Dictionary tagParams) + private string TagTempChangeUpAlarm(Dictionary tagParams) { if (cumulus.TempChangeAlarm.Enabled) { @@ -4178,7 +4178,7 @@ private string TagTempChangeUpAlarm(Dictionary tagParams) return "0"; } - private string TagTempChangeDownAlarm(Dictionary tagParams) + private string TagTempChangeDownAlarm(Dictionary tagParams) { if (cumulus.TempChangeAlarm.Enabled) { @@ -4188,7 +4188,7 @@ private string TagTempChangeDownAlarm(Dictionary tagParams) return "0"; } - private string TagLowPressAlarm(Dictionary tagParams) + private string TagLowPressAlarm(Dictionary tagParams) { if (cumulus.LowPressAlarm.Enabled) { @@ -4198,7 +4198,7 @@ private string TagLowPressAlarm(Dictionary tagParams) return "0"; } - private string TagHighPressAlarm(Dictionary tagParams) + private string TagHighPressAlarm(Dictionary tagParams) { if (cumulus.HighPressAlarm.Enabled) { @@ -4208,7 +4208,7 @@ private string TagHighPressAlarm(Dictionary tagParams) return "0"; } - private string TagPressChangeUpAlarm(Dictionary tagParams) + private string TagPressChangeUpAlarm(Dictionary tagParams) { if (cumulus.PressChangeAlarm.Enabled) { @@ -4218,7 +4218,7 @@ private string TagPressChangeUpAlarm(Dictionary tagParams) return "0"; } - private string TagPressChangeDownAlarm(Dictionary tagParams) + private string TagPressChangeDownAlarm(Dictionary tagParams) { if (cumulus.PressChangeAlarm.Enabled) { @@ -4228,7 +4228,7 @@ private string TagPressChangeDownAlarm(Dictionary tagParams) return "0"; } - private string TagHighRainTodayAlarm(Dictionary tagParams) + private string TagHighRainTodayAlarm(Dictionary tagParams) { if (cumulus.HighRainTodayAlarm.Enabled) { @@ -4238,7 +4238,7 @@ private string TagHighRainTodayAlarm(Dictionary tagParams) return "0"; } - private string TagHighRainRateAlarm(Dictionary tagParams) + private string TagHighRainRateAlarm(Dictionary tagParams) { if (cumulus.HighRainRateAlarm.Enabled) { @@ -4258,17 +4258,17 @@ private string TagIsRainingAlarm(Dictionary tagParams) return "0"; } - private string TagHighWindGustAlarm(Dictionary tagParams) + private string TagHighWindGustAlarm(Dictionary tagParams) { if (cumulus.HighGustAlarm.Enabled) { - return cumulus.HighGustAlarm.Triggered? "1" : "0"; + return cumulus.HighGustAlarm.Triggered ? "1" : "0"; } return "0"; } - private string TagHighWindSpeedAlarm(Dictionary tagParams) + private string TagHighWindSpeedAlarm(Dictionary tagParams) { if (cumulus.HighWindAlarm.Enabled) { @@ -4330,32 +4330,32 @@ private string TagHttpUploadAlarm(Dictionary tagParams) // Monthly highs and lows - values - private string TagMonthTempH(Dictionary tagParams) + private string TagMonthTempH(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ThisMonth.HighTemp.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagMonthTempL(Dictionary tagParams) + private string TagMonthTempL(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ThisMonth.LowTemp.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagMonthHeatIndexH(Dictionary tagParams) + private string TagMonthHeatIndexH(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ThisMonth.HighHeatIndex.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagMonthWChillL(Dictionary tagParams) + private string TagMonthWChillL(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ThisMonth.LowChill.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagMonthAppTempH(Dictionary tagParams) + private string TagMonthAppTempH(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ThisMonth.HighAppTemp.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagMonthAppTempL(Dictionary tagParams) + private string TagMonthAppTempL(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ThisMonth.LowAppTemp.Val, tagParams), tagParams, cumulus.TempDPlaces); } @@ -4375,72 +4375,72 @@ private string TagMonthHumidexH(Dictionary tagParams) return CheckRcDp(station.ThisMonth.HighHumidex.Val, tagParams, cumulus.TempDPlaces); } - private string TagMonthDewPointH(Dictionary tagParams) + private string TagMonthDewPointH(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ThisMonth.HighDewPoint.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagMonthDewPointL(Dictionary tagParams) + private string TagMonthDewPointL(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ThisMonth.LowDewPoint.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagMonthMinTempH(Dictionary tagParams) + private string TagMonthMinTempH(Dictionary tagParams) { return station.ThisMonth.HighMinTemp.Val > -999 ? CheckRcDp(CheckTempUnit(station.ThisMonth.HighMinTemp.Val, tagParams), tagParams, cumulus.TempDPlaces) : "--"; } - private string TagMonthMaxTempL(Dictionary tagParams) + private string TagMonthMaxTempL(Dictionary tagParams) { return station.ThisMonth.LowMaxTemp.Val < 999 ? CheckRcDp(CheckTempUnit(station.ThisMonth.LowMaxTemp.Val, tagParams), tagParams, cumulus.TempDPlaces) : "--"; } - private string TagMonthPressH(Dictionary tagParams) + private string TagMonthPressH(Dictionary tagParams) { return CheckRcDp(CheckPressUnit(station.ThisMonth.HighPress.Val, tagParams), tagParams, cumulus.PressDPlaces); } - private string TagMonthPressL(Dictionary tagParams) + private string TagMonthPressL(Dictionary tagParams) { return CheckRcDp(CheckPressUnit(station.ThisMonth.LowPress.Val, tagParams), tagParams, cumulus.PressDPlaces); } - private string TagMonthHumH(Dictionary tagParams) + private string TagMonthHumH(Dictionary tagParams) { return station.ThisMonth.HighHumidity.Val.ToString(cumulus.HumFormat); } - private string TagMonthHumL(Dictionary tagParams) + private string TagMonthHumL(Dictionary tagParams) { return station.ThisMonth.LowHumidity.Val.ToString(cumulus.HumFormat); } - private string TagMonthGustH(Dictionary tagParams) + private string TagMonthGustH(Dictionary tagParams) { return CheckRcDp(CheckWindUnit(station.ThisMonth.HighGust.Val, tagParams), tagParams, cumulus.WindDPlaces); } - private string TagMonthWindH(Dictionary tagParams) + private string TagMonthWindH(Dictionary tagParams) { return CheckRcDp(CheckWindUnit(station.ThisMonth.HighWind.Val, tagParams), tagParams, cumulus.WindAvgDPlaces); } - private string TagMonthWindRunH(Dictionary tagParams) + private string TagMonthWindRunH(Dictionary tagParams) { return CheckRcDp(CheckWindRunUnit(station.ThisMonth.HighWindRun.Val, tagParams), tagParams, cumulus.WindRunDPlaces); } - private string TagMonthRainRateH(Dictionary tagParams) + private string TagMonthRainRateH(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.ThisMonth.HighRainRate.Val, tagParams), tagParams, cumulus.RainDPlaces); } - private string TagMonthHourlyRainH(Dictionary tagParams) + private string TagMonthHourlyRainH(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.ThisMonth.HourlyRain.Val, tagParams), tagParams, cumulus.RainDPlaces); } - private string TagMonthDailyRainH(Dictionary tagParams) + private string TagMonthDailyRainH(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.ThisMonth.DailyRain.Val, tagParams), tagParams, cumulus.RainDPlaces); } @@ -4450,53 +4450,53 @@ private string TagMonthRain24HourH(Dictionary tagParams) return CheckRcDp(CheckRainUnit(station.ThisMonth.HighRain24Hours.Val, tagParams), tagParams, cumulus.RainDPlaces); } - private string TagMonthLongestDryPeriod(Dictionary tagParams) + private string TagMonthLongestDryPeriod(Dictionary tagParams) { return station.ThisMonth.LongestDryPeriod.Val == Cumulus.DefaultHiVal ? "--" : station.ThisMonth.LongestDryPeriod.Val.ToString(); } - private string TagMonthLongestWetPeriod(Dictionary tagParams) + private string TagMonthLongestWetPeriod(Dictionary tagParams) { return station.ThisMonth.LongestWetPeriod.Val == Cumulus.DefaultHiVal ? "--" : station.ThisMonth.LongestWetPeriod.Val.ToString(); } - private string TagMonthHighDailyTempRange(Dictionary tagParams) + private string TagMonthHighDailyTempRange(Dictionary tagParams) { return station.ThisMonth.HighDailyTempRange.Val > -999 ? CheckRcDp(CheckTempUnitAbs(station.ThisMonth.HighDailyTempRange.Val, tagParams), tagParams, cumulus.TempDPlaces) : "--"; } - private string TagMonthLowDailyTempRange(Dictionary tagParams) + private string TagMonthLowDailyTempRange(Dictionary tagParams) { return station.ThisMonth.LowDailyTempRange.Val < 999 ? CheckRcDp(CheckTempUnitAbs(station.ThisMonth.LowDailyTempRange.Val, tagParams), tagParams, cumulus.TempDPlaces) : "--"; } // Monthly highs and lows - times - private string TagMonthTempHt(Dictionary tagParams) + private string TagMonthTempHt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.HighTemp.Ts, "t", tagParams); } - private string TagMonthTempLt(Dictionary tagParams) + private string TagMonthTempLt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.LowTemp.Ts, "t", tagParams); } - private string TagMonthHeatIndexHt(Dictionary tagParams) + private string TagMonthHeatIndexHt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.HighHeatIndex.Ts, "t", tagParams); } - private string TagMonthWChillLt(Dictionary tagParams) + private string TagMonthWChillLt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.LowChill.Ts, "t", tagParams); } - private string TagMonthAppTempHt(Dictionary tagParams) + private string TagMonthAppTempHt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.HighAppTemp.Ts, "t", tagParams); } - private string TagMonthAppTempLt(Dictionary tagParams) + private string TagMonthAppTempLt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.LowAppTemp.Ts, "t", tagParams); } @@ -4516,52 +4516,52 @@ private string TagMonthHumidexHt(Dictionary tagParams) return GetFormattedDateTime(station.ThisMonth.HighHumidex.Ts, "t", tagParams); } - private string TagMonthDewPointHt(Dictionary tagParams) + private string TagMonthDewPointHt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.HighDewPoint.Ts, "t", tagParams); } - private string TagMonthDewPointLt(Dictionary tagParams) + private string TagMonthDewPointLt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.LowDewPoint.Ts, "t", tagParams); } - private string TagMonthPressHt(Dictionary tagParams) + private string TagMonthPressHt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.HighPress.Ts, "t", tagParams); } - private string TagMonthPressLt(Dictionary tagParams) + private string TagMonthPressLt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.LowPress.Ts, "t", tagParams); } - private string TagMonthHumHt(Dictionary tagParams) + private string TagMonthHumHt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.HighHumidity.Ts, "t", tagParams); } - private string TagMonthHumLt(Dictionary tagParams) + private string TagMonthHumLt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.LowHumidity.Ts, "t", tagParams); } - private string TagMonthGustHt(Dictionary tagParams) + private string TagMonthGustHt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.HighGust.Ts, "t", tagParams); } - private string TagMonthWindHt(Dictionary tagParams) + private string TagMonthWindHt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.HighWind.Ts, "t", tagParams); } - private string TagMonthRainRateHt(Dictionary tagParams) + private string TagMonthRainRateHt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.HighRainRate.Ts, "t", tagParams); } - private string TagMonthHourlyRainHt(Dictionary tagParams) + private string TagMonthHourlyRainHt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.HourlyRain.Ts, "t", tagParams); } @@ -4572,32 +4572,32 @@ private string TagMonthRain24HourHt(Dictionary tagParams) } // Monthly highs and lows - dates - private string TagMonthTempHd(Dictionary tagParams) + private string TagMonthTempHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.HighTemp.Ts, "dd MMMM", tagParams); } - private string TagMonthTempLd(Dictionary tagParams) + private string TagMonthTempLd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.LowTemp.Ts, "dd MMMM", tagParams); } - private string TagMonthHeatIndexHd(Dictionary tagParams) + private string TagMonthHeatIndexHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.HighHeatIndex.Ts, "dd MMMM", tagParams); } - private string TagMonthWChillLd(Dictionary tagParams) + private string TagMonthWChillLd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.LowChill.Ts, "dd MMMM", tagParams); } - private string TagMonthAppTempHd(Dictionary tagParams) + private string TagMonthAppTempHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.HighAppTemp.Ts, "dd MMMM", tagParams); } - private string TagMonthAppTempLd(Dictionary tagParams) + private string TagMonthAppTempLd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.LowAppTemp.Ts, "dd MMMM", tagParams); } @@ -4617,62 +4617,62 @@ private string TagMonthHumidexHd(Dictionary tagParams) return GetFormattedDateTime(station.ThisMonth.HighHumidex.Ts, "dd MMMM", tagParams); } - private string TagMonthDewPointHd(Dictionary tagParams) + private string TagMonthDewPointHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.HighDewPoint.Ts, "dd MMMM", tagParams); } - private string TagMonthDewPointLd(Dictionary tagParams) + private string TagMonthDewPointLd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.LowDewPoint.Ts, "dd MMMM", tagParams); } - private string TagMonthMinTempHd(Dictionary tagParams) + private string TagMonthMinTempHd(Dictionary tagParams) { return station.ThisMonth.HighMinTemp.Val > -999 ? GetFormattedDateTime(station.ThisMonth.HighMinTemp.Ts, "dd MMMM", tagParams) : "---"; } - private string TagMonthMaxTempLd(Dictionary tagParams) + private string TagMonthMaxTempLd(Dictionary tagParams) { return station.ThisMonth.LowMaxTemp.Val < 999 ? GetFormattedDateTime(station.ThisMonth.LowMaxTemp.Ts, "dd MMMM", tagParams) : "---"; } - private string TagMonthPressHd(Dictionary tagParams) + private string TagMonthPressHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.HighPress.Ts, "dd MMMM", tagParams); } - private string TagMonthPressLd(Dictionary tagParams) + private string TagMonthPressLd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.LowPress.Ts, "dd MMMM", tagParams); } - private string TagMonthHumHd(Dictionary tagParams) + private string TagMonthHumHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.HighHumidity.Ts, "dd MMMM", tagParams); } - private string TagMonthHumLd(Dictionary tagParams) + private string TagMonthHumLd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.LowHumidity.Ts, "dd MMMM", tagParams); } - private string TagMonthGustHd(Dictionary tagParams) + private string TagMonthGustHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.HighGust.Ts, "dd MMMM", tagParams); } - private string TagMonthWindHd(Dictionary tagParams) + private string TagMonthWindHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.HighWind.Ts, "dd MMMM", tagParams); } - private string TagMonthRainRateHd(Dictionary tagParams) + private string TagMonthRainRateHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.HighRainRate.Ts, "dd MMMM", tagParams); } - private string TagMonthHourlyRainHd(Dictionary tagParams) + private string TagMonthHourlyRainHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.HourlyRain.Ts, "dd MMMM", tagParams); } @@ -4682,63 +4682,63 @@ private string TagMonthRain24HourHd(Dictionary tagParams) return GetFormattedDateTime(station.ThisMonth.HighRain24Hours.Ts, "dd MMMM", tagParams); } - private string TagMonthHighDailyTempRangeD(Dictionary tagParams) + private string TagMonthHighDailyTempRangeD(Dictionary tagParams) { return station.ThisMonth.HighDailyTempRange.Val < 999 ? GetFormattedDateTime(station.ThisMonth.HighDailyTempRange.Ts, "dd MMMM", tagParams) : "------"; } - private string TagMonthLowDailyTempRangeD(Dictionary tagParams) + private string TagMonthLowDailyTempRangeD(Dictionary tagParams) { return station.ThisMonth.LowDailyTempRange.Val > -999 ? GetFormattedDateTime(station.ThisMonth.LowDailyTempRange.Ts, "dd MMMM", tagParams) : "------"; } - private string TagMonthWindRunHd(Dictionary tagParams) + private string TagMonthWindRunHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.HighWindRun.Ts, "dd MMMM", tagParams); } - private string TagMonthDailyRainHd(Dictionary tagParams) + private string TagMonthDailyRainHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisMonth.DailyRain.Ts, "dd MMMM", tagParams); } - private string TagMonthLongestDryPeriodD(Dictionary tagParams) + private string TagMonthLongestDryPeriodD(Dictionary tagParams) { return station.ThisMonth.LongestDryPeriod.Val == Cumulus.DefaultHiVal ? "--" : GetFormattedDateTime(station.ThisMonth.LongestDryPeriod.Ts, "dd MMMM", tagParams); } - private string TagMonthLongestWetPeriodD(Dictionary tagParams) + private string TagMonthLongestWetPeriodD(Dictionary tagParams) { return station.ThisMonth.LongestWetPeriod.Val == Cumulus.DefaultHiVal ? "--" : GetFormattedDateTime(station.ThisMonth.LongestWetPeriod.Ts, "dd MMMM", tagParams); } // Yearly highs and lows - values - private string TagYearTempH(Dictionary tagParams) + private string TagYearTempH(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ThisYear.HighTemp.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagYearTempL(Dictionary tagParams) + private string TagYearTempL(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ThisYear.LowTemp.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagYearHeatIndexH(Dictionary tagParams) + private string TagYearHeatIndexH(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ThisYear.HighHeatIndex.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagYearWChillL(Dictionary tagParams) + private string TagYearWChillL(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ThisYear.LowChill.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagYearAppTempH(Dictionary tagParams) + private string TagYearAppTempH(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ThisYear.HighAppTemp.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagYearAppTempL(Dictionary tagParams) + private string TagYearAppTempL(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ThisYear.LowAppTemp.Val, tagParams), tagParams, cumulus.TempDPlaces); } @@ -4758,72 +4758,72 @@ private string TagYearHumidexH(Dictionary tagParams) return CheckRcDp(station.ThisYear.HighHumidex.Val, tagParams, cumulus.TempDPlaces); } - private string TagYearDewPointH(Dictionary tagParams) + private string TagYearDewPointH(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ThisYear.HighDewPoint.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagYearDewPointL(Dictionary tagParams) + private string TagYearDewPointL(Dictionary tagParams) { return CheckRcDp(CheckTempUnit(station.ThisYear.LowDewPoint.Val, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagYearMinTempH(Dictionary tagParams) + private string TagYearMinTempH(Dictionary tagParams) { return station.ThisYear.HighMinTemp.Val > -999 ? CheckRcDp(CheckTempUnit(station.ThisYear.HighMinTemp.Val, tagParams), tagParams, cumulus.TempDPlaces) : "--"; } - private string TagYearMaxTempL(Dictionary tagParams) + private string TagYearMaxTempL(Dictionary tagParams) { return station.ThisYear.LowMaxTemp.Val < 999 ? CheckRcDp(CheckTempUnit(station.ThisYear.LowMaxTemp.Val, tagParams), tagParams, cumulus.TempDPlaces) : "--"; } - private string TagYearPressH(Dictionary tagParams) + private string TagYearPressH(Dictionary tagParams) { return CheckRcDp(CheckPressUnit(station.ThisYear.HighPress.Val, tagParams), tagParams, cumulus.PressDPlaces); } - private string TagYearPressL(Dictionary tagParams) + private string TagYearPressL(Dictionary tagParams) { return CheckRcDp(CheckPressUnit(station.ThisYear.LowPress.Val, tagParams), tagParams, cumulus.PressDPlaces); } - private string TagYearHumH(Dictionary tagParams) + private string TagYearHumH(Dictionary tagParams) { return station.ThisYear.HighHumidity.Val.ToString(cumulus.HumFormat); } - private string TagYearHumL(Dictionary tagParams) + private string TagYearHumL(Dictionary tagParams) { return station.ThisYear.LowHumidity.Val.ToString(cumulus.HumFormat); } - private string TagYearGustH(Dictionary tagParams) + private string TagYearGustH(Dictionary tagParams) { return CheckRcDp(CheckWindUnit(station.ThisYear.HighGust.Val, tagParams), tagParams, cumulus.WindDPlaces); } - private string TagYearWindH(Dictionary tagParams) + private string TagYearWindH(Dictionary tagParams) { return CheckRcDp(CheckWindUnit(station.ThisYear.HighWind.Val, tagParams), tagParams, cumulus.WindAvgDPlaces); } - private string TagYearWindRunH(Dictionary tagParams) + private string TagYearWindRunH(Dictionary tagParams) { return CheckRcDp(CheckWindRunUnit(station.ThisYear.HighWindRun.Val, tagParams), tagParams, cumulus.WindRunDPlaces); } - private string TagYearRainRateH(Dictionary tagParams) + private string TagYearRainRateH(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.ThisYear.HighRainRate.Val, tagParams), tagParams, cumulus.RainDPlaces); } - private string TagYearHourlyRainH(Dictionary tagParams) + private string TagYearHourlyRainH(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.ThisYear.HourlyRain.Val, tagParams), tagParams, cumulus.RainDPlaces); } - private string TagYearDailyRainH(Dictionary tagParams) + private string TagYearDailyRainH(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.ThisYear.DailyRain.Val, tagParams), tagParams, cumulus.RainDPlaces); } @@ -4833,58 +4833,58 @@ private string TagYearRain24HourH(Dictionary tagParams) return CheckRcDp(CheckRainUnit(station.ThisYear.HighRain24Hours.Val, tagParams), tagParams, cumulus.RainDPlaces); } - private string TagYearLongestDryPeriod(Dictionary tagParams) + private string TagYearLongestDryPeriod(Dictionary tagParams) { return station.ThisYear.LongestDryPeriod.Val == Cumulus.DefaultHiVal ? "--" : station.ThisYear.LongestDryPeriod.Val.ToString(); } - private string TagYearLongestWetPeriod(Dictionary tagParams) + private string TagYearLongestWetPeriod(Dictionary tagParams) { return station.ThisYear.LongestWetPeriod.Val == Cumulus.DefaultHiVal ? "--" : station.ThisYear.LongestWetPeriod.Val.ToString(); } - private string TagYearHighDailyTempRange(Dictionary tagParams) + private string TagYearHighDailyTempRange(Dictionary tagParams) { return station.ThisYear.HighDailyTempRange.Val > -999 ? CheckRcDp(CheckTempUnitAbs(station.ThisYear.HighDailyTempRange.Val, tagParams), tagParams, cumulus.TempDPlaces) : "--"; } - private string TagYearLowDailyTempRange(Dictionary tagParams) + private string TagYearLowDailyTempRange(Dictionary tagParams) { return station.ThisYear.LowDailyTempRange.Val < 999 ? CheckRcDp(CheckTempUnitAbs(station.ThisYear.LowDailyTempRange.Val, tagParams), tagParams, cumulus.TempDPlaces) : "--"; } - private string TagYearMonthlyRainH(Dictionary tagParams) + private string TagYearMonthlyRainH(Dictionary tagParams) { return CheckRcDp(CheckRainUnit(station.ThisYear.MonthlyRain.Val, tagParams), tagParams, cumulus.RainDPlaces); } // Yearly highs and lows - times - private string TagYearTempHt(Dictionary tagParams) + private string TagYearTempHt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HighTemp.Ts, "t", tagParams); } - private string TagYearTempLt(Dictionary tagParams) + private string TagYearTempLt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.LowTemp.Ts, "t", tagParams); } - private string TagYearHeatIndexHt(Dictionary tagParams) + private string TagYearHeatIndexHt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HighHeatIndex.Ts, "t", tagParams); } - private string TagYearWChillLt(Dictionary tagParams) + private string TagYearWChillLt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.LowChill.Ts, "t", tagParams); } - private string TagYearAppTempHt(Dictionary tagParams) + private string TagYearAppTempHt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HighAppTemp.Ts, "t", tagParams); } - private string TagYearAppTempLt(Dictionary tagParams) + private string TagYearAppTempLt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.LowAppTemp.Ts, "t", tagParams); } @@ -4903,52 +4903,52 @@ private string TagYearHumidexHt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HighHumidex.Ts, "t", tagParams); } - private string TagYearDewPointHt(Dictionary tagParams) + private string TagYearDewPointHt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HighDewPoint.Ts, "t", tagParams); } - private string TagYearDewPointLt(Dictionary tagParams) + private string TagYearDewPointLt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.LowDewPoint.Ts, "t", tagParams); } - private string TagYearPressHt(Dictionary tagParams) + private string TagYearPressHt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HighPress.Ts, "t", tagParams); } - private string TagYearPressLt(Dictionary tagParams) + private string TagYearPressLt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.LowPress.Ts, "t", tagParams); } - private string TagYearHumHt(Dictionary tagParams) + private string TagYearHumHt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HighHumidity.Ts, "t", tagParams); } - private string TagYearHumLt(Dictionary tagParams) + private string TagYearHumLt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.LowHumidity.Ts, "t", tagParams); } - private string TagYearGustHt(Dictionary tagParams) + private string TagYearGustHt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HighGust.Ts, "t", tagParams); } - private string TagYearWindHt(Dictionary tagParams) + private string TagYearWindHt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HighWind.Ts, "t", tagParams); } - private string TagYearRainRateHt(Dictionary tagParams) + private string TagYearRainRateHt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HighRainRate.Ts, "t", tagParams); } - private string TagYearHourlyRainHt(Dictionary tagParams) + private string TagYearHourlyRainHt(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HourlyRain.Ts, "t", tagParams); } @@ -4959,32 +4959,32 @@ private string TagYearRain24HourHt(Dictionary tagParams) } // Yearly highs and lows - dates - private string TagYearTempHd(Dictionary tagParams) + private string TagYearTempHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HighTemp.Ts, "dd MMMM", tagParams); } - private string TagYearTempLd(Dictionary tagParams) + private string TagYearTempLd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.LowTemp.Ts, "dd MMMM", tagParams); } - private string TagYearHeatIndexHd(Dictionary tagParams) + private string TagYearHeatIndexHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HighHeatIndex.Ts, "dd MMMM", tagParams); } - private string TagYearWChillLd(Dictionary tagParams) + private string TagYearWChillLd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.LowChill.Ts, "dd MMMM", tagParams); } - private string TagYearAppTempHd(Dictionary tagParams) + private string TagYearAppTempHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HighAppTemp.Ts, "dd MMMM", tagParams); } - private string TagYearAppTempLd(Dictionary tagParams) + private string TagYearAppTempLd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.LowAppTemp.Ts, "dd MMMM", tagParams); } @@ -5004,62 +5004,62 @@ private string TagYearHumidexHd(Dictionary tagParams) return GetFormattedDateTime(station.ThisYear.HighHumidex.Ts, "dd MMMM", tagParams); } - private string TagYearDewPointHd(Dictionary tagParams) + private string TagYearDewPointHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HighDewPoint.Ts, "dd MMMM", tagParams); } - private string TagYearDewPointLd(Dictionary tagParams) + private string TagYearDewPointLd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.LowDewPoint.Ts, "dd MMMM", tagParams); } - private string TagYearMinTempHd(Dictionary tagParams) + private string TagYearMinTempHd(Dictionary tagParams) { return station.ThisYear.HighMinTemp.Val > -999 ? GetFormattedDateTime(station.ThisYear.HighMinTemp.Ts, "dd MMMM", tagParams) : "---"; } - private string TagYearMaxTempLd(Dictionary tagParams) + private string TagYearMaxTempLd(Dictionary tagParams) { return station.ThisYear.LowMaxTemp.Val < 999 ? GetFormattedDateTime(station.ThisYear.LowMaxTemp.Ts, "dd MMMM", tagParams) : "---"; } - private string TagYearPressHd(Dictionary tagParams) + private string TagYearPressHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HighPress.Ts, "dd MMMM", tagParams); } - private string TagYearPressLd(Dictionary tagParams) + private string TagYearPressLd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.LowPress.Ts, "dd MMMM", tagParams); } - private string TagYearHumHd(Dictionary tagParams) + private string TagYearHumHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HighHumidity.Ts, "dd MMMM", tagParams); } - private string TagYearHumLd(Dictionary tagParams) + private string TagYearHumLd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.LowHumidity.Ts, "dd MMMM", tagParams); } - private string TagYearGustHd(Dictionary tagParams) + private string TagYearGustHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HighGust.Ts, "dd MMMM", tagParams); } - private string TagYearWindHd(Dictionary tagParams) + private string TagYearWindHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HighWind.Ts, "dd MMMM", tagParams); } - private string TagYearRainRateHd(Dictionary tagParams) + private string TagYearRainRateHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HighRainRate.Ts, "dd MMMM", tagParams); } - private string TagYearHourlyRainHd(Dictionary tagParams) + private string TagYearHourlyRainHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HourlyRain.Ts, "dd MMMM", tagParams); } @@ -5069,74 +5069,74 @@ private string TagYearRain24HourHd(Dictionary tagParams) return GetFormattedDateTime(station.ThisYear.HighRain24Hours.Ts, "dd MMMM", tagParams); } - private string TagYearHighDailyTempRangeD(Dictionary tagParams) + private string TagYearHighDailyTempRangeD(Dictionary tagParams) { return station.ThisYear.HighDailyTempRange.Val > -999 ? GetFormattedDateTime(station.ThisYear.HighDailyTempRange.Ts, "dd MMMM", tagParams) : "------"; } - private string TagYearLowDailyTempRangeD(Dictionary tagParams) + private string TagYearLowDailyTempRangeD(Dictionary tagParams) { return station.ThisYear.LowDailyTempRange.Val < 999 ? GetFormattedDateTime(station.ThisYear.LowDailyTempRange.Ts, "dd MMMM", tagParams) : "------"; } - private string TagYearWindRunHd(Dictionary tagParams) + private string TagYearWindRunHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.HighWindRun.Ts, "dd MMMM", tagParams); } - private string TagYearDailyRainHd(Dictionary tagParams) + private string TagYearDailyRainHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.DailyRain.Ts, "dd MMMM", tagParams); } - private string TagYearLongestDryPeriodD(Dictionary tagParams) + private string TagYearLongestDryPeriodD(Dictionary tagParams) { return station.ThisYear.LongestDryPeriod.Val == Cumulus.DefaultHiVal ? "--" : GetFormattedDateTime(station.ThisYear.LongestDryPeriod.Ts, "dd MMMM", tagParams); } - private string TagYearLongestWetPeriodD(Dictionary tagParams) + private string TagYearLongestWetPeriodD(Dictionary tagParams) { return station.ThisYear.LongestWetPeriod.Val == Cumulus.DefaultHiVal ? "--" : GetFormattedDateTime(station.ThisYear.LongestWetPeriod.Ts, "dd MMMM", tagParams); } - private string TagYearMonthlyRainHd(Dictionary tagParams) + private string TagYearMonthlyRainHd(Dictionary tagParams) { return GetFormattedDateTime(station.ThisYear.MonthlyRain.Ts, "MMMM", tagParams); } //------------------------------------------------------------ - private string TagLastDataReadT(Dictionary tagParams) + private string TagLastDataReadT(Dictionary tagParams) { - return GetFormattedDateTime(station.LastDataReadTimestamp, "G",tagParams); + return GetFormattedDateTime(station.LastDataReadTimestamp, "G", tagParams); } - private string TagLatestError(Dictionary tagParams) + private string TagLatestError(Dictionary tagParams) { return cumulus.LatestError; } - private string TagLatestErrorDate(Dictionary tagParams) + private string TagLatestErrorDate(Dictionary tagParams) { return cumulus.LatestErrorTS == DateTime.MinValue ? "------" : GetFormattedDateTime(cumulus.LatestErrorTS, "ddddd", tagParams); } - private string TagLatestErrorTime(Dictionary tagParams) + private string TagLatestErrorTime(Dictionary tagParams) { return cumulus.LatestErrorTS == DateTime.MinValue ? "------" : GetFormattedDateTime(cumulus.LatestErrorTS, "t", tagParams); } - private static string TagOsVersion(Dictionary tagParams) + private static string TagOsVersion(Dictionary tagParams) { return Environment.OSVersion.ToString(); } - private static string TagOsLanguage(Dictionary tagParams) + private static string TagOsLanguage(Dictionary tagParams) { return CultureInfo.CurrentCulture.DisplayName; } - private string TagSystemUpTime(Dictionary tagParams) + private string TagSystemUpTime(Dictionary tagParams) { try { @@ -5172,7 +5172,7 @@ private string TagSystemUpTime(Dictionary tagParams) } } - private static string TagProgramUpTime(Dictionary tagParams) + private static string TagProgramUpTime(Dictionary tagParams) { // Bug in Mono Process.StartTime - wraps after 24 days TimeSpan ts = DateTime.Now - Program.StartTime; @@ -5186,37 +5186,37 @@ private static string TagProgramUpTimeMs(Dictionary tagParams) return ts.TotalMilliseconds.ToString(); } - private static string TagCpuName(Dictionary tagParams) + private static string TagCpuName(Dictionary tagParams) { return "n/a"; } - private static string TagCpuCount(Dictionary tagParams) + private static string TagCpuCount(Dictionary tagParams) { return Environment.ProcessorCount.ToString(); } - private static string TagMemoryStatus(Dictionary tagParams) + private static string TagMemoryStatus(Dictionary tagParams) { return "n/a"; } - private static string TagDisplayModeString(Dictionary tagParams) + private static string TagDisplayModeString(Dictionary tagParams) { return "n/a"; } - private static string TagAllocatedMemory(Dictionary tagParams) + private static string TagAllocatedMemory(Dictionary tagParams) { - return (Environment.WorkingSet/1048576.0).ToString("F2") + " MB"; + return (Environment.WorkingSet / 1048576.0).ToString("F2") + " MB"; } - private static string TagDiskSize(Dictionary tagParams) + private static string TagDiskSize(Dictionary tagParams) { return "n/a"; } - private static string TagDiskFree(Dictionary tagParams) + private static string TagDiskFree(Dictionary tagParams) { return "n/a"; } @@ -5226,30 +5226,30 @@ private string TagCpuTemp(Dictionary tagParams) return cumulus.CPUtemp.ToString(cumulus.TempFormat); } - private string TagDavisTotalPacketsReceived(Dictionary tagParams) + private string TagDavisTotalPacketsReceived(Dictionary tagParams) { return station.DavisTotalPacketsReceived.ToString(); } - private string TagDavisTotalPacketsMissed(Dictionary tagParams) + private string TagDavisTotalPacketsMissed(Dictionary tagParams) { int tx = int.TryParse(tagParams.Get("tx"), out tx) ? tx : 0; // Default to transmitter 0=VP2 return station.DavisTotalPacketsMissed[tx].ToString(); } - private string TagDavisNumberOfResynchs(Dictionary tagParams) + private string TagDavisNumberOfResynchs(Dictionary tagParams) { int tx = int.TryParse(tagParams.Get("tx"), out tx) ? tx : 0; // Default to transmitter 0=VP2 return station.DavisNumberOfResynchs[tx].ToString(); } - private string TagDavisMaxInARow(Dictionary tagParams) + private string TagDavisMaxInARow(Dictionary tagParams) { int tx = int.TryParse(tagParams.Get("tx"), out tx) ? tx : 0; // Default to transmitter 0=VP2 return station.DavisMaxInARow[tx].ToString(); } - private string TagDavisNumCrCerrors(Dictionary tagParams) + private string TagDavisNumCrCerrors(Dictionary tagParams) { int tx = int.TryParse(tagParams.Get("tx"), out tx) ? tx : 0; // Default to transmitter 0=VP2 return station.DavisNumCRCerrors[tx].ToString(); @@ -5267,7 +5267,7 @@ private string TagDavisTxRssi(Dictionary tagParams) return station.DavisTxRssi[tx].ToString(); } - private string TagDavisFirmwareVersion(Dictionary tagParams) + private string TagDavisFirmwareVersion(Dictionary tagParams) { return station.DavisFirmwareVersion; } @@ -5277,13 +5277,35 @@ private string TagGw1000FirmwareVersion(Dictionary tagParams) return station.GW1000FirmwareVersion; } + private string TagGw1000Reception(Dictionary tagParams) + { + var retVal = string.Empty; + + if (WeatherStation.SensorReception.Count > 0) + { + foreach (var pair in WeatherStation.SensorReception) + { + retVal += pair.Key + "=" + pair.Value + ","; + } + + return retVal.Remove(retVal.Length - 1); + } + else + { + retVal = "n/a"; + } + + return retVal; + } + + private string Tagdailygraphperiod(Dictionary tagparams) { return cumulus.GraphDays.ToString(); } // Recent history - private string TagRecentOutsideTemp(Dictionary tagParams) + private string TagRecentOutsideTemp(Dictionary tagParams) { var recentTs = GetRecentTs(tagParams); @@ -5292,7 +5314,7 @@ private string TagRecentOutsideTemp(Dictionary tagParams) return CheckRcDp(CheckTempUnit(result.Count == 0 ? station.OutdoorTemperature : result[0].OutsideTemp, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagRecentWindSpeed(Dictionary tagParams) + private string TagRecentWindSpeed(Dictionary tagParams) { var recentTs = GetRecentTs(tagParams); @@ -5301,7 +5323,7 @@ private string TagRecentWindSpeed(Dictionary tagParams) return CheckRcDp(CheckWindUnit(result.Count == 0 ? station.WindAverage : result[0].WindSpeed, tagParams), tagParams, cumulus.WindAvgDPlaces); } - private string TagRecentWindGust(Dictionary tagParams) + private string TagRecentWindGust(Dictionary tagParams) { var recentTs = GetRecentTs(tagParams); @@ -5310,7 +5332,7 @@ private string TagRecentWindGust(Dictionary tagParams) return CheckRcDp(CheckWindUnit(result.Count == 0 ? station.RecentMaxGust : result[0].WindGust, tagParams), tagParams, cumulus.WindDPlaces); } - private string TagRecentWindLatest(Dictionary tagParams) + private string TagRecentWindLatest(Dictionary tagParams) { var recentTs = GetRecentTs(tagParams); @@ -5319,7 +5341,7 @@ private string TagRecentWindLatest(Dictionary tagParams) return CheckRcDp(CheckWindUnit(result.Count == 0 ? station.WindLatest : result[0].WindLatest, tagParams), tagParams, cumulus.WindDPlaces); } - private string TagRecentWindDir(Dictionary tagParams) + private string TagRecentWindDir(Dictionary tagParams) { var recentTs = GetRecentTs(tagParams); @@ -5328,7 +5350,7 @@ private string TagRecentWindDir(Dictionary tagParams) return result.Count == 0 ? station.Bearing.ToString() : result[0].WindDir.ToString(); } - private string TagRecentWindAvgDir(Dictionary tagParams) + private string TagRecentWindAvgDir(Dictionary tagParams) { var recentTs = GetRecentTs(tagParams); @@ -5337,7 +5359,7 @@ private string TagRecentWindAvgDir(Dictionary tagParams) return result.Count != 0 ? result[0].WindAvgDir.ToString() : station.AvgBearing.ToString(); } - private string TagRecentWindChill(Dictionary tagParams) + private string TagRecentWindChill(Dictionary tagParams) { var recentTs = GetRecentTs(tagParams); @@ -5346,7 +5368,7 @@ private string TagRecentWindChill(Dictionary tagParams) return CheckRcDp(CheckTempUnit(result.Count == 0 ? station.WindChill : result[0].WindChill, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagRecentDewPoint(Dictionary tagParams) + private string TagRecentDewPoint(Dictionary tagParams) { var recentTs = GetRecentTs(tagParams); @@ -5355,7 +5377,7 @@ private string TagRecentDewPoint(Dictionary tagParams) return CheckRcDp(CheckTempUnit(result.Count == 0 ? station.OutdoorDewpoint : result[0].DewPoint, tagParams), tagParams, cumulus.TempDPlaces); } - private string TagRecentHeatIndex(Dictionary tagParams) + private string TagRecentHeatIndex(Dictionary tagParams) { var recentTs = GetRecentTs(tagParams); @@ -5382,7 +5404,7 @@ private string TagRecentHumidex(Dictionary tagParams) return CheckRcDp(result.Count == 0 ? station.Humidex : result[0].Humidex, tagParams, cumulus.TempDPlaces); } - private string TagRecentHumidity(Dictionary tagParams) + private string TagRecentHumidity(Dictionary tagParams) { var recentTs = GetRecentTs(tagParams); @@ -5391,7 +5413,7 @@ private string TagRecentHumidity(Dictionary tagParams) return result.Count == 0 ? station.OutdoorHumidity.ToString() : result[0].Humidity.ToString(); } - private string TagRecentPressure(Dictionary tagParams) + private string TagRecentPressure(Dictionary tagParams) { var recentTs = GetRecentTs(tagParams); @@ -5404,7 +5426,33 @@ private string TagRecentRain(Dictionary tagParams) { var recentTs = GetRecentTs(tagParams); - var result = station.RecentDataDb.ExecuteScalar("select (select raincounter from RecentData order by Timestamp Desc limit 1) - raincounter from RecentData where Timestamp >= ? order by Timestamp limit 1", recentTs); + double? result = null; + // pesky raincounter can reset, so first we have to test if it has. + // get the max value + var max = station.RecentDataDb.Query("select Timestamp, max(raincounter) from RecentData where Timestamp >= ?", recentTs); + // get the last value + var last = station.RecentDataDb.ExecuteScalar("select raincounter from RecentData order by Timestamp Desc limit 1"); + + if (max.Count == 1 && last.HasValue) + { + if (last < max[0].raincounter) + { + // Counter has reset - we assume only one reset in the period. If there is more than one then this will fail + // First part = max_value - start_value + var start = station.RecentDataDb.ExecuteScalar("select raincounter from RecentData where Timestamp >= ? order by Timestamp limit 1", recentTs); + result = max[0].raincounter - start; + + // Now add on any increment since the reset + var resetval = station.RecentDataDb.ExecuteScalar("select raincounter from RecentData where Timestamp > ? order by Timestamp limit 1", max[0].Timestamp); + + result += last - resetval; + } + else + { + // No counter reset + result = station.RecentDataDb.ExecuteScalar("select (select raincounter from RecentData order by Timestamp Desc limit 1) - raincounter from RecentData where Timestamp >= ? order by Timestamp limit 1", recentTs); + } + } return CheckRcDp(CheckPressUnit(result.HasValue ? result.Value : station.RainToday, tagParams), tagParams, cumulus.RainDPlaces); } @@ -6321,6 +6369,8 @@ public void InitialiseWebtags() { "DavisFirmwareVersion", TagDavisFirmwareVersion }, { "DavisTxRssi", TagDavisTxRssi }, { "GW1000FirmwareVersion", TagGw1000FirmwareVersion }, + { "EcowittFirmwareVersion", TagGw1000FirmwareVersion }, + { "EcowittReception", TagGw1000Reception }, { "DataStopped", TagDataStopped }, // Recent history { "RecentOutsideTemp", TagRecentOutsideTemp }, diff --git a/Updates.txt b/Updates.txt index edfc20b2..78f7ca6d 100644 --- a/Updates.txt +++ b/Updates.txt @@ -15,7 +15,10 @@ New - Adds new alarm for any all-time record being set - Adds new alarm "Web upload errors" for errors in the FTP/PHP upload processes - Adds the ability to append free text comments to the wxnow.txt file. You can also include web tags -- New web tag for recent rainfall - <#RecentRain> - it takes the same parameters as the other RecentXxxx web tags, and defaults to todays total if the parameters are incorrect or no recent data is available +- New web tag for recent rainfall - <#RecentRain> - it takes the same parameters as the other RecentXxxx web tags, and defaults to today's total if the parameters are incorrect or no recent data is available +- New web tag for Ecowitt sensor radio reception strength - <#EcowittReception> - it returns a string of comma separated sensor names and value. eg "WH80=4,WH41CH1=3" + The values are updated every 20 minutes along with the battery info +- New alternative name for the existing web tag <#GW1000FirmwareVersion>, you can now use <#EcowittFirmwareVersion> Changed - Various third party libraries updated to current versions @@ -32,6 +35,8 @@ Fixed - Instromet station now forces MX to calculate the average wind speed - FTP logging errors when FTP logging is already enabled at start-up - Updating MySQL on DayFile edits was erroring with a blank SQL statement +- Davis stations spike in wind speed on stop/start of CMX + From 97f8f58a7c2013c8354eebd6a27c118cd321e4f0 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Thu, 3 Aug 2023 16:33:39 +0100 Subject: [PATCH 25/27] Add a parameter "format=json" - <#EcowittReception format=json> Web tag <#txbattery> now also supports the format=json parameter Adds Custom MySQL commands for when Cumulus starts up --- CumulusMX/Cumulus.cs | 51 +++++++++++++++++++++++++++- CumulusMX/MysqlSettings.cs | 43 ++++++++++++++++++++--- CumulusMX/Properties/AssemblyInfo.cs | 6 ++-- CumulusMX/Utils.cs | 7 ++-- CumulusMX/webtags.cs | 47 +++++++++++++++++++++---- Updates.txt | 12 ++++--- 6 files changed, 144 insertions(+), 22 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index 0202a133..fc06ac29 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -1646,6 +1646,12 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) InitialiseRG11(); + // Do the start-up MySQL commands before the station is started + if (MySqlSettings.CustomStartUp.Enabled) + { + CustomMySqlStartUp(); + } + if (station.timerStartNeeded) { StartTimersAndSensors(); @@ -5673,7 +5679,6 @@ private void ReadIniFile() MySqlSettings.CustomTimed.SetInitialNextInterval(i, DateTime.Now); } - // MySQL - custom roll-over MySqlSettings.CustomRollover.Enabled = ini.GetValue("MySQL", "CustomMySqlRolloverEnabled", false); MySqlSettings.CustomRollover.Commands[0] = ini.GetValue("MySQL", "CustomMySqlRolloverCommandString", ""); @@ -5683,6 +5688,15 @@ private void ReadIniFile() MySqlSettings.CustomRollover.Commands[i] = ini.GetValue("MySQL", "CustomMySqlRolloverCommandString" + i, ""); } + // MySQL - custom start-up + MySqlSettings.CustomStartUp.Enabled = ini.GetValue("MySQL", "CustomMySqlStartUpEnabled", false); + MySqlSettings.CustomStartUp.Commands[0] = ini.GetValue("MySQL", "CustomMySqlStartUpCommandString", ""); + for (var i = 1; i < 10; i++) + { + if (ini.ValueExists("MySQL", "CustomMySqlStartUpCommandString" + i)) + MySqlSettings.CustomStartUp.Commands[i] = ini.GetValue("MySQL", "CustomMySqlStartUpCommandString" + i, ""); + } + // Custom HTTP - seconds CustomHttpSecondsStrings[0] = ini.GetValue("HTTP", "CustomHttpSecondsString", ""); @@ -6823,6 +6837,7 @@ internal void WriteIniFile() ini.SetValue("MySQL", "CustomMySqlSecondsEnabled", MySqlSettings.CustomSecs.Enabled); ini.SetValue("MySQL", "CustomMySqlMinutesEnabled", MySqlSettings.CustomMins.Enabled); ini.SetValue("MySQL", "CustomMySqlRolloverEnabled", MySqlSettings.CustomRollover.Enabled); + ini.SetValue("MySQL", "CustomMySqlStartUpEnabled", MySqlSettings.CustomStartUp.Enabled); ini.SetValue("MySQL", "CustomMySqlSecondsInterval", MySqlSettings.CustomSecs.Interval); ini.SetValue("MySQL", "CustomMySqlMinutesIntervalIndex", CustomMySqlMinutesIntervalIndex); @@ -6830,6 +6845,7 @@ internal void WriteIniFile() ini.SetValue("MySQL", "CustomMySqlSecondsCommandString", MySqlSettings.CustomSecs.Commands[0]); ini.SetValue("MySQL", "CustomMySqlMinutesCommandString", MySqlSettings.CustomMins.Commands[0]); ini.SetValue("MySQL", "CustomMySqlRolloverCommandString", MySqlSettings.CustomRollover.Commands[0]); + ini.SetValue("MySQL", "CustomMySqlStartUpCommandString", MySqlSettings.CustomStartUp.Commands[0]); for (var i = 1; i < 10; i++) { @@ -6847,6 +6863,11 @@ internal void WriteIniFile() ini.DeleteValue("MySQL", "CustomMySqlRolloverCommandString" + i); else ini.SetValue("MySQL", "CustomMySqlRolloverCommandString" + i, MySqlSettings.CustomRollover.Commands[i]); + + if (string.IsNullOrEmpty(MySqlSettings.CustomStartUp.Commands[i])) + ini.DeleteValue("MySQL", "CustomMySqlStartUpCommandString" + i); + else + ini.SetValue("MySQL", "CustomMySqlStartUpCommandString" + i, MySqlSettings.CustomStartUp.Commands[i]); } // MySql - Timed @@ -12269,6 +12290,30 @@ internal async void CustomMySqlTimedUpdate(DateTime now) } } + internal void CustomMySqlStartUp() + { + LogMessage("Starting custom start-up MySQL commands"); + + var tokenParser = new TokenParser(TokenParserOnToken); + + for (var i = 0; i < 10; i++) + { + try + { + if (!string.IsNullOrEmpty(MySqlSettings.CustomStartUp.Commands[i])) + { + tokenParser.InputText = MySqlSettings.CustomStartUp.Commands[i]; + MySqlCommandSync(tokenParser.ToStringFromString(), "CustomMySqlStartUp"); + } + } + catch (Exception ex) + { + LogExceptionMessage(ex, $"CustomSqlStartUp[{i}]: Error excuting: {MySqlSettings.CustomStartUp.Commands[i]} "); + } + } + LogMessage("Custom start-up MySQL commands end"); + } + public async Task CheckMySQLFailedUploads(string callingFunction, string cmd) { await CheckMySQLFailedUploads(callingFunction, new List() { cmd }); @@ -14031,6 +14076,8 @@ public class MySqlGeneralSettings public MySqlTableSettings CustomMins { get; set; } public MySqlTableSettings CustomRollover { get; set; } public MySqlTableTimedSettings CustomTimed { get; set; } + public MySqlTableSettings CustomStartUp { get; set; } + public MySqlGeneralSettings() { @@ -14041,6 +14088,7 @@ public MySqlGeneralSettings() CustomMins = new MySqlTableSettings(); CustomRollover = new MySqlTableSettings(); CustomTimed = new MySqlTableTimedSettings(); + CustomStartUp = new MySqlTableSettings(); CustomSecs.Commands = new string[10]; CustomMins.Commands = new string[10]; @@ -14049,6 +14097,7 @@ public MySqlGeneralSettings() CustomTimed.Intervals = new int[10]; CustomTimed.StartTimes = new TimeSpan[10]; CustomTimed.NextUpdate = new DateTime[10]; + CustomStartUp.Commands = new string[10]; } } diff --git a/CumulusMX/MysqlSettings.cs b/CumulusMX/MysqlSettings.cs index 35e2fd40..fed1a21c 100644 --- a/CumulusMX/MysqlSettings.cs +++ b/CumulusMX/MysqlSettings.cs @@ -103,7 +103,7 @@ public string GetAlpacaFormData() customminutes.command[index++] = cumulus.MySqlSettings.CustomMins.Commands[i]; } - var customrollover = new JsonSettingsCustomRollover() + var customrollover = new JsonSettingsCustomRolloverStart() { enabled = cumulus.MySqlSettings.CustomRollover.Enabled }; @@ -158,6 +158,26 @@ public string GetAlpacaFormData() } } + var customstartup = new JsonSettingsCustomRolloverStart() + { + enabled = cumulus.MySqlSettings.CustomStartUp.Enabled + }; + + cmdCnt = 1; + for (var i = 1; i < 10; i++) + { + if (!string.IsNullOrEmpty(cumulus.MySqlSettings.CustomStartUp.Commands[i])) + cmdCnt++; + } + customstartup.command = new string[cmdCnt]; + + index = 0; + for (var i = 0; i < 10; i++) + { + if (!string.IsNullOrEmpty(cumulus.MySqlSettings.CustomStartUp.Commands[i])) + customstartup.command[index++] = cumulus.MySqlSettings.CustomStartUp.Commands[i]; + } + var options = new JsonSettingsOptions() { updateonedit = cumulus.MySqlSettings.UpdateOnEdit, @@ -175,7 +195,8 @@ public string GetAlpacaFormData() customseconds = customseconds, customminutes = customminutes, customrollover = customrollover, - customtimed = customtimed + customtimed = customtimed, + customstart = customstartup }; return data.ToJson(); @@ -310,7 +331,6 @@ public string UpdateConfig(IHttpContext context) else cumulus.MySqlSettings.CustomRollover.Commands[i] = null; } - } // custom timed cumulus.MySqlSettings.CustomTimed.Enabled = settings.customtimed.enabled; @@ -334,6 +354,18 @@ public string UpdateConfig(IHttpContext context) } } } + // custom start-up + cumulus.MySqlSettings.CustomStartUp.Enabled = settings.customstart.enabled; + if (cumulus.MySqlSettings.CustomStartUp.Enabled) + { + for (var i = 0; i < 10; i++) + { + if (i < settings.customstart.command.Length) + cumulus.MySqlSettings.CustomStartUp.Commands[i] = String.IsNullOrWhiteSpace(settings.customstart.command[i]) ? null : settings.customstart.command[i].Trim(); + else + cumulus.MySqlSettings.CustomStartUp.Commands[i] = null; + } + } // Save the settings cumulus.WriteIniFile(); @@ -495,8 +527,9 @@ private class JsonSettings public JsonSettingsDayfile dayfile { get; set; } public JsonSettingsCustomSeconds customseconds { get; set; } public JsonSettingsCustomMinutes customminutes { get; set; } - public JsonSettingsCustomRollover customrollover { get; set; } + public JsonSettingsCustomRolloverStart customrollover { get; set; } public JsonSettingsCustomTimed customtimed { get; set; } + public JsonSettingsCustomRolloverStart customstart { get; set; } } private class JsonSettingsServer @@ -549,7 +582,7 @@ private class JsonSettingsCustomMinutes public int intervalindex { get; set; } } - private class JsonSettingsCustomRollover + private class JsonSettingsCustomRolloverStart { public bool enabled { get; set; } public string[] command { get; set; } diff --git a/CumulusMX/Properties/AssemblyInfo.cs b/CumulusMX/Properties/AssemblyInfo.cs index 349af213..676f6ee8 100644 --- a/CumulusMX/Properties/AssemblyInfo.cs +++ b/CumulusMX/Properties/AssemblyInfo.cs @@ -6,7 +6,7 @@ // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("Cumulus MX")] -[assembly: AssemblyDescription("Version 3.26.0 - Build 3246")] +[assembly: AssemblyDescription("Version 3.26.0 - Build 3247")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Cumulus MX")] @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("3.26.0.3246")] -[assembly: AssemblyFileVersion("3.26.0.3246")] +[assembly: AssemblyVersion("3.26.0.3247")] +[assembly: AssemblyFileVersion("3.26.0.3247")] diff --git a/CumulusMX/Utils.cs b/CumulusMX/Utils.cs index e123d1a2..1fbf16af 100644 --- a/CumulusMX/Utils.cs +++ b/CumulusMX/Utils.cs @@ -219,9 +219,12 @@ public static string ExceptionToString(Exception ex) sb.AppendLine("Exception Type: " + ex.GetType().FullName); sb.AppendLine("Message: " + ex.Message); //sb.AppendLine("Source: " + ex.Source); - foreach (var key in ex.Data.Keys) + if (ex.Data.Keys.Count > 0) { - sb.AppendLine(key.ToString() + ": " + ex.Data[key].ToString()); + foreach (var key in ex.Data.Keys) + { + sb.AppendLine(key.ToString() + ": " + (ex.Data[key] is null ? "null" : ex.Data[key].ToString())); + } } /* diff --git a/CumulusMX/webtags.cs b/CumulusMX/webtags.cs index 7ae55780..8890a7ca 100644 --- a/CumulusMX/webtags.cs +++ b/CumulusMX/webtags.cs @@ -1105,20 +1105,39 @@ private string TagConsoleSupplyV(Dictionary tagParams) private string Tagtxbattery(Dictionary tagParams) { + var json = tagParams.Get("format") == "json"; + if (string.IsNullOrEmpty(station.TxBatText)) { - return ""; + return json ? "{}" : ""; } + string[] sl; + string channeltxt = tagParams.Get("channel"); if (channeltxt == null) { - return station.TxBatText; + if (json) + { + var retVal = "{"; + sl = station.TxBatText.Split(' '); + + for (var i = 0; i < sl.Length; i++) + { + retVal += $"\"TX{i + 1}\":\"{sl[i].Substring(2)}\","; + } + + return retVal.Remove(retVal.Length - 1) + "}"; + } + else + { + return station.TxBatText; + } } // extract status for required channel char[] delimiters = { ' ', '-' }; - string[] sl = station.TxBatText.Split(delimiters); + sl = station.TxBatText.Split(delimiters); int channel = int.Parse(channeltxt) * 2 - 1; @@ -5279,20 +5298,34 @@ private string TagGw1000FirmwareVersion(Dictionary tagParams) private string TagGw1000Reception(Dictionary tagParams) { - var retVal = string.Empty; + var json = tagParams.Get("format") == "json"; + + var retVal = json ? "{" : string.Empty; + if (WeatherStation.SensorReception.Count > 0) { foreach (var pair in WeatherStation.SensorReception) { - retVal += pair.Key + "=" + pair.Value + ","; + if (json) + { + retVal += $"\"{pair.Key}\":{pair.Value},"; + } + else + { + retVal += $"{pair.Key}={pair.Value},"; + } } - return retVal.Remove(retVal.Length - 1); + retVal = retVal.Remove(retVal.Length - 1); + + retVal += json ? "}" : ""; + + return retVal; } else { - retVal = "n/a"; + retVal = json ? "{}" : "n/a"; } return retVal; diff --git a/Updates.txt b/Updates.txt index 78f7ca6d..65cc59a6 100644 --- a/Updates.txt +++ b/Updates.txt @@ -1,4 +1,4 @@ -3.26.0 - b3246 +3.26.0 - b3247 —————————————— New - MQTT has a new behaviour - Only update a topic if the data has changed @@ -16,9 +16,13 @@ New - Adds new alarm "Web upload errors" for errors in the FTP/PHP upload processes - Adds the ability to append free text comments to the wxnow.txt file. You can also include web tags - New web tag for recent rainfall - <#RecentRain> - it takes the same parameters as the other RecentXxxx web tags, and defaults to today's total if the parameters are incorrect or no recent data is available -- New web tag for Ecowitt sensor radio reception strength - <#EcowittReception> - it returns a string of comma separated sensor names and value. eg "WH80=4,WH41CH1=3" - The values are updated every 20 minutes along with the battery info +- New web tag for Ecowitt sensor radio reception strength - <#EcowittReception> + - By default it returns a string of comma separated sensor names and value. eg "WH80=4,WH41CH1=3" + - You can add a parameter "format=json" - <#EcowittReception format=json> - and it will return a valid JSON string. eg. {"WH80":4,"WH41CH1":3} + - The values are updated every 20 minutes along with the battery info +- The existing web tag <#txbattery> now also supports the format=json parameter which functions the same as #EcowittReception tag above - New alternative name for the existing web tag <#GW1000FirmwareVersion>, you can now use <#EcowittFirmwareVersion> +- Adds Custom MySQL commands for when Cumulus starts up. These will be executed after the station is initialised, but before it start any historic catch-up or live processing Changed - Various third party libraries updated to current versions @@ -35,7 +39,7 @@ Fixed - Instromet station now forces MX to calculate the average wind speed - FTP logging errors when FTP logging is already enabled at start-up - Updating MySQL on DayFile edits was erroring with a blank SQL statement -- Davis stations spike in wind speed on stop/start of CMX +- Davis stations spike in average wind speed on stop/start of CMX From 7d5b3ab8d2c3a1aa72815d9c4c26ccd2ff170052 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Mon, 7 Aug 2023 14:26:15 +0100 Subject: [PATCH 26/27] Addition PHP exception logging --- CumulusMX/Cumulus.cs | 4 ++-- CumulusMX/CumulusMX.csproj | 2 +- CumulusMX/Properties/AssemblyInfo.cs | 6 +++--- Updates.txt | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index fc06ac29..491f1ab6 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -1740,7 +1740,7 @@ internal async void TestPhpUploadCompression() } catch (Exception ex) { - LogMessage("TestPhpUploadCompression: Error - " + ex.Message); + LogExceptionMessage(ex, "TestPhpUploadCompression: Error - "); } } } @@ -2844,7 +2844,7 @@ internal void RealtimeTimerTick(object sender, ElapsedEventArgs elapsedEventArgs } catch (Exception ex) { - LogMessage($"Realtime[{cycle}]: Error during realtime upload. Message = {ex.Message}"); + LogExceptionMessage(ex, $"Realtime[{cycle}]: Error during realtime upload."); } RealtimeFtpInProgress = false; } diff --git a/CumulusMX/CumulusMX.csproj b/CumulusMX/CumulusMX.csproj index 4a60c95b..4f808224 100644 --- a/CumulusMX/CumulusMX.csproj +++ b/CumulusMX/CumulusMX.csproj @@ -251,7 +251,7 @@ 2.2.5 - 6.9.0 + 6.10.0 2020.0.2 diff --git a/CumulusMX/Properties/AssemblyInfo.cs b/CumulusMX/Properties/AssemblyInfo.cs index 676f6ee8..179b7566 100644 --- a/CumulusMX/Properties/AssemblyInfo.cs +++ b/CumulusMX/Properties/AssemblyInfo.cs @@ -6,7 +6,7 @@ // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("Cumulus MX")] -[assembly: AssemblyDescription("Version 3.26.0 - Build 3247")] +[assembly: AssemblyDescription("Version 3.26.0 - Build 3248")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Cumulus MX")] @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("3.26.0.3247")] -[assembly: AssemblyFileVersion("3.26.0.3247")] +[assembly: AssemblyVersion("3.26.0.3248")] +[assembly: AssemblyFileVersion("3.26.0.3248")] diff --git a/Updates.txt b/Updates.txt index 65cc59a6..68e16f53 100644 --- a/Updates.txt +++ b/Updates.txt @@ -22,7 +22,7 @@ New - The values are updated every 20 minutes along with the battery info - The existing web tag <#txbattery> now also supports the format=json parameter which functions the same as #EcowittReception tag above - New alternative name for the existing web tag <#GW1000FirmwareVersion>, you can now use <#EcowittFirmwareVersion> -- Adds Custom MySQL commands for when Cumulus starts up. These will be executed after the station is initialised, but before it start any historic catch-up or live processing +- Adds Custom MySQL commands for when Cumulus starts up. These will be executed after the station is initialised, but before it starts any historic catch-up or live processing Changed - Various third party libraries updated to current versions From 7740e579dbf9235731f6ea99db0a74e39d04e371 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Wed, 9 Aug 2023 11:21:42 +0100 Subject: [PATCH 27/27] Update post build tasks Remove some unused variables --- CumulusMX/Alarm.cs | 2 +- CumulusMX/CumulusMX.csproj | 16 ++++++++++++++-- CumulusMX/DavisAirLink.cs | 2 -- CumulusMX/DavisStation.cs | 2 -- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/CumulusMX/Alarm.cs b/CumulusMX/Alarm.cs index f5638cde..4abfc13f 100644 --- a/CumulusMX/Alarm.cs +++ b/CumulusMX/Alarm.cs @@ -245,7 +245,7 @@ public bool DownTriggered } } - public void ClearAlarm() + public new void ClearAlarm() { if (Latch && upTriggered && DateTime.Now > UpTriggeredTime.AddHours(LatchHours)) doUpTriggered(false); diff --git a/CumulusMX/CumulusMX.csproj b/CumulusMX/CumulusMX.csproj index 4f808224..5cacc453 100644 --- a/CumulusMX/CumulusMX.csproj +++ b/CumulusMX/CumulusMX.csproj @@ -265,10 +265,22 @@ - echo Starting post-build tasks + echo. +echo Starting post-build tasks +echo Copy Updates.txt xcopy "$(ProjectDir)..\Updates.txt" "$(TargetDir)\Updates.txt" /D /-I /Q /Y +echo copy sqlite 32 xcopy "$(ProjectDir)\Libs\sqlite3-x86.dll" "$(TargetDir)\x86\sqlite3.dll" /D /-I /Q /Y -xcopy "$(ProjectDir)\Libs\sqlite3-x64.dll" "$(TargetDir)\x64\sqlite3.dll" /D /-I /Q /Y +echo copy sqlite 64 +xcopy "$(ProjectDir)\Libs\sqlite3-x64.dll" "$(TargetDir)\x64\sqlite3.dll" /D /-I /Q /Y +echo. +echo Update Distribution folder +echo copy MX exe +xcopy "$(TargetPath)" "$(SolutionDir)..\CumulusMX-Dist\CumulusMX" /D /-I /Q /Y +echo copy MX config +xcopy "$(TargetDir)CumulusMX.exe.config" "$(SolutionDir)..\CumulusMX-Dist\CumulusMX" /D /-I /Q /Y + +