From a45fd15c5bd3e01cdbb877a7505112bfa7d62a58 Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Mon, 22 Aug 2022 14:20:05 +0100 Subject: [PATCH 01/12] Remove Program references from Alarms --- CumulusMX/Alarm.cs | 14 +++++++------- CumulusMX/Properties/AssemblyInfo.cs | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CumulusMX/Alarm.cs b/CumulusMX/Alarm.cs index 6b61e5f3..7534982d 100644 --- a/CumulusMX/Alarm.cs +++ b/CumulusMX/Alarm.cs @@ -17,7 +17,7 @@ public bool Triggered get => triggered; set { - if (Program.cumulus.NormalRunning) + if (cumulus.NormalRunning) { doTriggered(value); } @@ -49,7 +49,7 @@ public Alarm(string AlarmName, AlarmTypes AlarmType) public void CheckAlarm(double value) { - if (Program.cumulus.NormalRunning) + if (cumulus.NormalRunning) { doTriggered((type == AlarmTypes.Above && value > Value) || (type == AlarmTypes.Below && value < Value)); } @@ -147,7 +147,7 @@ public bool UpTriggered get => upTriggered; set { - if (Program.cumulus.NormalRunning) + if (cumulus.NormalRunning) { doUpTriggered(value); } @@ -162,7 +162,7 @@ public bool DownTriggered get => downTriggered; set { - if (Program.cumulus.NormalRunning) + if (cumulus.NormalRunning) { doDownTriggered(value); } @@ -174,7 +174,7 @@ public bool DownTriggered public new void CheckAlarm(double value) { - if (Program.cumulus.NormalRunning) + if (cumulus.NormalRunning) { if (value > Value) @@ -209,7 +209,7 @@ private void doUpTriggered(bool value) cumulus.LogMessage($"Alarm ({Name}): Sending email"); // Construct the message - preamble, plus values - var msg = Program.cumulus.AlarmEmailPreamble + "\r\n" + string.Format(EmailMsgUp, Value, Units); + var msg = cumulus.AlarmEmailPreamble + "\r\n" + string.Format(EmailMsgUp, Value, Units); cumulus.emailer.SendEmail(cumulus.AlarmDestEmail, cumulus.AlarmFromEmail, cumulus.AlarmEmailSubject, msg, cumulus.AlarmEmailHtml); } @@ -274,7 +274,7 @@ private void doDownTriggered(bool value) { cumulus.LogMessage($"Alarm ({Name}): Sending email"); // Construct the message - preamble, plus values - var msg = Program.cumulus.AlarmEmailPreamble + "\n" + string.Format(EmailMsgDn, Value, Units); + var msg = cumulus.AlarmEmailPreamble + "\n" + string.Format(EmailMsgDn, Value, Units); cumulus.emailer.SendEmail(cumulus.AlarmDestEmail, cumulus.AlarmFromEmail, cumulus.AlarmEmailSubject, msg, cumulus.AlarmEmailHtml); } diff --git a/CumulusMX/Properties/AssemblyInfo.cs b/CumulusMX/Properties/AssemblyInfo.cs index 422fef68..de4bd52f 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.20.0 - Build 3202")] +[assembly: AssemblyDescription("Version 3.20.1 - Build 3203")] [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.20.0.3202")] -[assembly: AssemblyFileVersion("3.20.0.3202")] +[assembly: AssemblyVersion("3.20.1.3203")] +[assembly: AssemblyFileVersion("3.20.1.3203")] From 9936ce3109ccb5ae75d1d6f33c9ed354a8ec9384 Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Tue, 23 Aug 2022 11:17:34 +0100 Subject: [PATCH 02/12] Change the MySQL table updates to compare column names rather than simple counts --- CumulusMX/Api.cs | 2 -- CumulusMX/Cumulus.cs | 2 +- CumulusMX/MysqlSettings.cs | 36 ++++++++++++++++++++++++++---------- Updates.txt | 8 ++++++++ 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/CumulusMX/Api.cs b/CumulusMX/Api.cs index a3cc3cec..46da1875 100644 --- a/CumulusMX/Api.cs +++ b/CumulusMX/Api.cs @@ -1443,7 +1443,5 @@ public async Task PostUtilsData(string req) } } } - - } } diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index fe071580..20e50d44 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -1670,7 +1670,7 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) station.CreateEodGraphDataFiles(); } - //LogDebugMessage("Lock: Cumulus releasing the lock"); + LogDebugMessage("Lock: Cumulus releasing the lock"); syncInit.Release(); } diff --git a/CumulusMX/MysqlSettings.cs b/CumulusMX/MysqlSettings.cs index 8be1e11c..928fef57 100644 --- a/CumulusMX/MysqlSettings.cs +++ b/CumulusMX/MysqlSettings.cs @@ -5,6 +5,8 @@ using ServiceStack; using EmbedIO; using System.Text; +using MySqlConnector.Logging; +using System.Collections.Generic; namespace CumulusMX { @@ -340,24 +342,38 @@ private string UpdateMySQLTable(MySqlTable table) { mySqlConn.Open(); - // first get a count of the columns the table currenty has - using (MySqlCommand cmd = new MySqlCommand($"SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='{table.Name}' AND TABLE_SCHEMA='{cumulus.MySqlConnSettings.Database}'", mySqlConn)) + // first get a list of the columns the table currenty has + var currCols = new List(); + using (MySqlCommand cmd = new MySqlCommand($"SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='{table.Name}' AND TABLE_SCHEMA='{cumulus.MySqlConnSettings.Database}'", mySqlConn)) { - colsNow = int.Parse(cmd.ExecuteScalar().ToString()); + using (MySqlDataReader reader = cmd.ExecuteReader()) + { + if (reader.HasRows) + { + while (reader.Read()) + { + var col = reader.GetString(0); + currCols.Add(col); + } + } + } } - if (colsNow < table.Columns.Count) + if (currCols.Count < table.Columns.Count) { var update = new StringBuilder("ALTER TABLE " + table.Name, 1024); - while (colsNow < table.Columns.Count) + foreach (var newCol in table.Columns) { - update.Append($" ADD COLUMN {table.Columns[colsNow].Name} {table.Columns[colsNow].Attributes},"); - colsNow++; - cnt++; + if (!currCols.Contains(newCol.Name)) + { + update.Append($" ADD COLUMN {newCol.Name} {newCol.Attributes},"); + cnt++; + } } // strip trailing comma - update.Length--; + if (cnt > 0) + update.Length--; using(MySqlCommand cmd = new MySqlCommand(update.ToString(), mySqlConn)) { @@ -369,7 +385,7 @@ private string UpdateMySQLTable(MySqlTable table) } else { - res = $"The {table.Name} already has the correct number of columns = {table.Columns.Count}"; + res = $"The {table.Name} already has the required columns = {table.Columns.Count}"; } } } diff --git a/Updates.txt b/Updates.txt index a010a698..ec1f339c 100644 --- a/Updates.txt +++ b/Updates.txt @@ -1,3 +1,11 @@ +3.20.1 - b3203 +—————————————— +Fixed +- Fix crash in Alarms with some station types +- Change the MySQL table updates to compare column names rather than simple counts +- Fix the All Time, Monthly, This Year records editors not allowing 24 hour rain values to be changed + + 3.20.0 - b3202 —————————————— Fixed From 100fd3162082c4e5d9dc7a305841d7458c2172e4 Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Tue, 23 Aug 2022 11:20:50 +0100 Subject: [PATCH 03/12] MySQL wording tweak --- CumulusMX/MysqlSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CumulusMX/MysqlSettings.cs b/CumulusMX/MysqlSettings.cs index 928fef57..8d1cc5e8 100644 --- a/CumulusMX/MysqlSettings.cs +++ b/CumulusMX/MysqlSettings.cs @@ -385,7 +385,7 @@ private string UpdateMySQLTable(MySqlTable table) } else { - res = $"The {table.Name} already has the required columns = {table.Columns.Count}"; + res = $"The {table.Name} table already has all the required columns = {table.Columns.Count}"; } } } From f7878d93fbdc8bbba032e6d4b09bff63a0c9e59c Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Tue, 23 Aug 2022 11:27:19 +0100 Subject: [PATCH 04/12] Code format tarting --- CumulusMX/MysqlSettings.cs | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/CumulusMX/MysqlSettings.cs b/CumulusMX/MysqlSettings.cs index 8d1cc5e8..c2e5908a 100644 --- a/CumulusMX/MysqlSettings.cs +++ b/CumulusMX/MysqlSettings.cs @@ -345,16 +345,14 @@ private string UpdateMySQLTable(MySqlTable table) // first get a list of the columns the table currenty has var currCols = new List(); using (MySqlCommand cmd = new MySqlCommand($"SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='{table.Name}' AND TABLE_SCHEMA='{cumulus.MySqlConnSettings.Database}'", mySqlConn)) + using (MySqlDataReader reader = cmd.ExecuteReader()) { - using (MySqlDataReader reader = cmd.ExecuteReader()) + if (reader.HasRows) { - if (reader.HasRows) + while (reader.Read()) { - while (reader.Read()) - { - var col = reader.GetString(0); - currCols.Add(col); - } + var col = reader.GetString(0); + currCols.Add(col); } } } @@ -373,14 +371,21 @@ private string UpdateMySQLTable(MySqlTable table) // strip trailing comma if (cnt > 0) + { update.Length--; - using(MySqlCommand cmd = new MySqlCommand(update.ToString(), mySqlConn)) - { - int aff = cmd.ExecuteNonQuery(); - cumulus.LogMessage($"MySQL Update Table: {aff} items were affected."); - res = $"Added {cnt} columns to {table.Name} table"; + using (MySqlCommand cmd = new MySqlCommand(update.ToString(), mySqlConn)) + { + int aff = cmd.ExecuteNonQuery(); + cumulus.LogMessage($"MySQL Update Table: {aff} items were affected."); + res = $"Added {cnt} columns to {table.Name} table"; + } + } + else + { + res = $"Error: The {table.Name} table does not have all the required columns, but failed to find the missing columns!"; + cumulus.LogMessage("MySQL Update Table: " + res); } } else From 3969b2952736dc54f8e83aacce514ceb95a49aec Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Tue, 23 Aug 2022 12:03:44 +0100 Subject: [PATCH 05/12] MySQL table update rethink! --- CumulusMX/MysqlSettings.cs | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/CumulusMX/MysqlSettings.cs b/CumulusMX/MysqlSettings.cs index c2e5908a..78308cd9 100644 --- a/CumulusMX/MysqlSettings.cs +++ b/CumulusMX/MysqlSettings.cs @@ -357,40 +357,32 @@ private string UpdateMySQLTable(MySqlTable table) } } - if (currCols.Count < table.Columns.Count) + var update = new StringBuilder("ALTER TABLE " + table.Name, 1024); + foreach (var newCol in table.Columns) { - var update = new StringBuilder("ALTER TABLE " + table.Name, 1024); - foreach (var newCol in table.Columns) + if (!currCols.Contains(newCol.Name)) { - if (!currCols.Contains(newCol.Name)) - { - update.Append($" ADD COLUMN {newCol.Name} {newCol.Attributes},"); - cnt++; - } + update.Append($" ADD COLUMN {newCol.Name} {newCol.Attributes},"); + cnt++; } + } + if (cnt > 0) + { // strip trailing comma - if (cnt > 0) - { - update.Length--; + update.Length--; - using (MySqlCommand cmd = new MySqlCommand(update.ToString(), mySqlConn)) - { - int aff = cmd.ExecuteNonQuery(); - cumulus.LogMessage($"MySQL Update Table: {aff} items were affected."); - res = $"Added {cnt} columns to {table.Name} table"; - - } - } - else + using (MySqlCommand cmd = new MySqlCommand(update.ToString(), mySqlConn)) { - res = $"Error: The {table.Name} table does not have all the required columns, but failed to find the missing columns!"; - cumulus.LogMessage("MySQL Update Table: " + res); + int aff = cmd.ExecuteNonQuery(); + res = $"Added {cnt} columns to {table.Name} table"; + cumulus.LogMessage($"MySQL Update Table: " + res); } } else { res = $"The {table.Name} table already has all the required columns = {table.Columns.Count}"; + cumulus.LogMessage("MySQL Update Table: " + res); } } } From 290e50dabdf25879eba387c7d5af7ec3f78cdc29 Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Wed, 24 Aug 2022 11:11:56 +0100 Subject: [PATCH 06/12] Change Lat/Long to decimal values Double check the emailer is available in Alarm --- CumulusMX/Alarm.cs | 6 +++--- CumulusMX/Cumulus.cs | 26 +++++++++++++------------- CumulusMX/IniFile.cs | 13 +++++++++++++ CumulusMX/NOAA.cs | 4 ++-- CumulusMX/Simulator.cs | 2 +- CumulusMX/StationSettings.cs | 12 ++++++------ CumulusMX/WeatherStation.cs | 6 +++--- CumulusMX/Wizard.cs | 10 +++++----- CumulusMX/webtags.cs | 28 ++++++++++++++++++++++++++-- Updates.txt | 3 +++ 10 files changed, 75 insertions(+), 35 deletions(-) diff --git a/CumulusMX/Alarm.cs b/CumulusMX/Alarm.cs index 7534982d..8ac7a461 100644 --- a/CumulusMX/Alarm.cs +++ b/CumulusMX/Alarm.cs @@ -70,7 +70,7 @@ private void doTriggered(bool value) { cumulus.LogMessage($"Alarm ({Name}): Triggered"); - if (Email && cumulus.SmtpOptions.Enabled) + if (Email && cumulus.SmtpOptions.Enabled && cumulus.emailer != null) { cumulus.LogMessage($"Alarm ({Name}): Sending email"); @@ -204,7 +204,7 @@ private void doUpTriggered(bool value) { cumulus.LogMessage($"Alarm ({Name}): Up triggered"); - if (Email && cumulus.SmtpOptions.Enabled) + if (Email && cumulus.SmtpOptions.Enabled && cumulus.emailer != null) { cumulus.LogMessage($"Alarm ({Name}): Sending email"); @@ -270,7 +270,7 @@ private void doDownTriggered(bool value) { cumulus.LogMessage($"Alarm ({Name}): Down triggered"); - if (Email && cumulus.SmtpOptions.Enabled) + if (Email && cumulus.SmtpOptions.Enabled && cumulus.emailer != null) { cumulus.LogMessage($"Alarm ({Name}): Sending email"); // Construct the message - preamble, plus values diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index 20e50d44..d0f2404f 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -447,8 +447,8 @@ public struct TExtraFiles public int RolloverHour; public bool Use10amInSummer; - public double Latitude; - public double Longitude; + public decimal Latitude; + public decimal Longitude; public double Altitude; internal int wsPort; @@ -3315,7 +3315,7 @@ private static bool IsRunningOnMac() internal void DoMoonPhase() { DateTime now = DateTime.Now; - double[] moonriseset = MoonriseMoonset.MoonRise(now.Year, now.Month, now.Day, TimeZone.CurrentTimeZone.GetUtcOffset(now).TotalHours, Latitude, Longitude); + double[] moonriseset = MoonriseMoonset.MoonRise(now.Year, now.Month, now.Day, TimeZone.CurrentTimeZone.GetUtcOffset(now).TotalHours, (double)Latitude, (double)Longitude); MoonRiseTime = TimeSpan.FromHours(moonriseset[0]); MoonSetTime = TimeSpan.FromHours(moonriseset[1]); @@ -3379,7 +3379,7 @@ internal void DoMoonImage() if (MoonImage.Enabled) { LogDebugMessage("Generating new Moon image"); - var ret = MoonriseMoonset.CreateMoonImage(MoonPhaseAngle, Latitude, MoonImage.Size); + var ret = MoonriseMoonset.CreateMoonImage(MoonPhaseAngle, (double)Latitude, MoonImage.Size); if (ret == "OK") { @@ -3457,8 +3457,8 @@ private string GetMoonStage(double fAge) private void GetSunriseSunset(DateTime time, out DateTime sunrise, out DateTime sunset, out bool alwaysUp, out bool alwaysDown) { - string rise = SunriseSunset.SunRise(time, TimeZone.CurrentTimeZone.GetUtcOffset(time).TotalHours, Longitude, Latitude); - string set = SunriseSunset.SunSet(time, TimeZone.CurrentTimeZone.GetUtcOffset(time).TotalHours, Longitude, Latitude); + string rise = SunriseSunset.SunRise(time, TimeZone.CurrentTimeZone.GetUtcOffset(time).TotalHours, (double) Longitude, (double) Latitude); + string set = SunriseSunset.SunSet(time, TimeZone.CurrentTimeZone.GetUtcOffset(time).TotalHours, (double) Longitude, (double) Latitude); if (rise.Equals("Always Down") || set.Equals("Always Down")) { @@ -3530,8 +3530,8 @@ private DateTime getSunsetTime(DateTime time) private void GetDawnDusk(DateTime time, out DateTime dawn, out DateTime dusk, out bool alwaysUp, out bool alwaysDown) { - string dawnStr = SunriseSunset.CivilTwilightEnds(time, TimeZone.CurrentTimeZone.GetUtcOffset(time).TotalHours, Longitude, Latitude); - string duskStr = SunriseSunset.CivilTwilightStarts(time, TimeZone.CurrentTimeZone.GetUtcOffset(time).TotalHours, Longitude, Latitude); + string dawnStr = SunriseSunset.CivilTwilightEnds(time, TimeZone.CurrentTimeZone.GetUtcOffset(time).TotalHours, (double) Longitude, (double) Latitude); + string duskStr = SunriseSunset.CivilTwilightStarts(time, TimeZone.CurrentTimeZone.GetUtcOffset(time).TotalHours, (double) Longitude, (double) Latitude); if (dawnStr.Equals("Always Down") || duskStr.Equals("Always Down")) { @@ -3950,14 +3950,14 @@ private void ReadIniFile() //VP2SleepInterval = ini.GetValue("Station", "VP2SleepInterval", 0); DavisOptions.PeriodicDisconnectInterval = ini.GetValue("Station", "VP2PeriodicDisconnectInterval", 0); - Latitude = ini.GetValue("Station", "Latitude", 0.0); + Latitude = ini.GetValue("Station", "Latitude", (decimal) 0.0); if (Latitude > 90 || Latitude < -90) { Latitude = 0; LogMessage($"Error, invalid latitude value in Cumulus.ini [{Latitude}], defaulting to zero."); rewriteRequired = true; } - Longitude = ini.GetValue("Station", "Longitude", 0.0); + Longitude = ini.GetValue("Station", "Longitude", (decimal) 0.0); if (Longitude > 180 || Longitude < -180) { Longitude = 0; @@ -6112,7 +6112,7 @@ internal void WriteIniFile() ini.SetValue("MySQL", "Host", MySqlConnSettings.Server); - ini.SetValue("MySQL", "Port", MySqlConnSettings.Port); + ini.SetValue("MySQL", "Port", (int) MySqlConnSettings.Port); ini.SetValue("MySQL", "User", MySqlConnSettings.UserID); ini.SetValue("MySQL", "Pass", MySqlConnSettings.Password); ini.SetValue("MySQL", "Database", MySqlConnSettings.Database); @@ -7026,7 +7026,7 @@ public async void DoLogFile(DateTime timestamp, bool live) // make sure solar max is calculated for those stations without a solar sensor LogMessage("DoLogFile: Writing log entry for " + timestamp); LogDebugMessage("DoLogFile: max gust: " + station.RecentMaxGust.ToString(WindFormat)); - station.CurrentSolarMax = AstroLib.SolarMax(timestamp, Longitude, Latitude, station.AltitudeM(Altitude), out station.SolarElevation, SolarOptions); + station.CurrentSolarMax = AstroLib.SolarMax(timestamp, (double) Longitude, (double) Latitude, station.AltitudeM(Altitude), out station.SolarElevation, SolarOptions); var filename = GetLogFileName(timestamp); var sb = new StringBuilder(256); @@ -10492,7 +10492,7 @@ public async void CustomHttpRolloverUpdate() } } - public void DegToDMS(double degrees, out int d, out int m, out int s) + public void DegToDMS(decimal degrees, out int d, out int m, out int s) { int secs = (int)(degrees * 60 * 60); diff --git a/CumulusMX/IniFile.cs b/CumulusMX/IniFile.cs index c6974cba..ad65221d 100644 --- a/CumulusMX/IniFile.cs +++ b/CumulusMX/IniFile.cs @@ -393,6 +393,14 @@ internal double GetValue(string SectionName, string Key, double DefaultValue) return DefaultValue; } + internal decimal GetValue(string SectionName, string Key, decimal DefaultValue) + { + string StringValue = GetValue(SectionName, Key, DefaultValue.ToString(CultureInfo.InvariantCulture)); + decimal Value; + if (decimal.TryParse(StringValue, NumberStyles.Any, CultureInfo.InvariantCulture, out Value)) return Value; + return DefaultValue; + } + internal byte[] GetValue(string SectionName, string Key, byte[] DefaultValue) { string StringValue = GetValue(SectionName, Key, EncodeByteArray(DefaultValue)); @@ -430,6 +438,11 @@ internal void SetValue(string SectionName, string Key, double Value) SetValue(SectionName, Key, Value.ToString("G17", CultureInfo.InvariantCulture)); } + internal void SetValue(string SectionName, string Key, decimal Value) + { + SetValue(SectionName, Key, Value.ToString(CultureInfo.InvariantCulture)); + } + internal void SetValue(string SectionName, string Key, byte[] Value) { SetValue(SectionName, Key, EncodeByteArray(Value)); diff --git a/CumulusMX/NOAA.cs b/CumulusMX/NOAA.cs index 89d833ff..6b61b775 100644 --- a/CumulusMX/NOAA.cs +++ b/CumulusMX/NOAA.cs @@ -103,12 +103,12 @@ private string CompassPoint(int bearing) return cumulus.compassp[(((bearing * 100) + 1125) % 36000) / 2250]; } - private static double Frac(double num) + private static decimal Frac(decimal num) { return num - Math.Floor(num); } - private void DecodeLatLong(double latLong, out int deg, out int min, out int sec) + private void DecodeLatLong(decimal latLong, out int deg, out int min, out int sec) { deg = (int) Math.Floor(latLong); latLong = Frac(latLong) * 60; diff --git a/CumulusMX/Simulator.cs b/CumulusMX/Simulator.cs index d49f0ef7..32a4bb7e 100644 --- a/CumulusMX/Simulator.cs +++ b/CumulusMX/Simulator.cs @@ -144,7 +144,7 @@ private void doSolar(DateTime recDate) // if we are starting up, set the intial solar rad value to 90% of theoretical if (!solarIntialised) { - CurrentSolarMax = AstroLib.SolarMax(recDate, cumulus.Longitude, cumulus.Latitude, AltitudeM(cumulus.Altitude), out SolarElevation, cumulus.SolarOptions); + CurrentSolarMax = AstroLib.SolarMax(recDate, (double) cumulus.Longitude, (double) cumulus.Latitude, AltitudeM(cumulus.Altitude), out SolarElevation, cumulus.SolarOptions); solar = CurrentSolarMax * 0.9; solarIntialised = true; } diff --git a/CumulusMX/StationSettings.cs b/CumulusMX/StationSettings.cs index 4e9316f9..877fac6a 100644 --- a/CumulusMX/StationSettings.cs +++ b/CumulusMX/StationSettings.cs @@ -489,9 +489,9 @@ internal string GetAlpacaFormData() return JsonSerializer.SerializeToString(data); } - private void LongToDMS(double longitude, out int d, out int m, out int s, out string hem) + private void LongToDMS(decimal longitude, out int d, out int m, out int s, out string hem) { - double coordinate; + decimal coordinate; if (longitude < 0) { coordinate = -longitude; @@ -512,9 +512,9 @@ private void LongToDMS(double longitude, out int d, out int m, out int s, out st d = secs / 60; } - private void LatToDMS(double latitude, out int d, out int m, out int s, out string hem) + private void LatToDMS(decimal latitude, out int d, out int m, out int s, out string hem) { - double coordinate; + decimal coordinate; if (latitude < 0) { coordinate = -latitude; @@ -720,7 +720,7 @@ internal string UpdateConfig(IHttpContext context) cumulus.LocationName = settings.general.Location.sitename ?? string.Empty; cumulus.LocationDesc = settings.general.Location.description ?? string.Empty; - cumulus.Latitude = settings.general.Location.Latitude.degrees + (settings.general.Location.Latitude.minutes / 60.0) + (settings.general.Location.Latitude.seconds / 3600.0); + cumulus.Latitude = (decimal) (settings.general.Location.Latitude.degrees + (settings.general.Location.Latitude.minutes / 60.0) + (settings.general.Location.Latitude.seconds / 3600.0)); if (settings.general.Location.Latitude.hemisphere == "South") { cumulus.Latitude = -cumulus.Latitude; @@ -729,7 +729,7 @@ internal string UpdateConfig(IHttpContext context) cumulus.LatTxt = string.Format("{0} {1:D2}° {2:D2}' {3:D2}"", settings.general.Location.Latitude.hemisphere[0], settings.general.Location.Latitude.degrees, settings.general.Location.Latitude.minutes, settings.general.Location.Latitude.seconds); - cumulus.Longitude = settings.general.Location.Longitude.degrees + (settings.general.Location.Longitude.minutes / 60.0) + (settings.general.Location.Longitude.seconds / 3600.0); + cumulus.Longitude = (decimal) (settings.general.Location.Longitude.degrees + (settings.general.Location.Longitude.minutes / 60.0) + (settings.general.Location.Longitude.seconds / 3600.0)); if (settings.general.Location.Longitude.hemisphere == "West") { cumulus.Longitude = -cumulus.Longitude; diff --git a/CumulusMX/WeatherStation.cs b/CumulusMX/WeatherStation.cs index 7aab7744..28b40ac5 100644 --- a/CumulusMX/WeatherStation.cs +++ b/CumulusMX/WeatherStation.cs @@ -1674,7 +1674,7 @@ private void MinuteChanged(DateTime now) { CheckForDataStopped(); - CurrentSolarMax = AstroLib.SolarMax(now, cumulus.Longitude, cumulus.Latitude, AltitudeM(cumulus.Altitude), out SolarElevation, cumulus.SolarOptions); + CurrentSolarMax = AstroLib.SolarMax(now, (double) cumulus.Longitude, (double) cumulus.Latitude, AltitudeM(cumulus.Altitude), out SolarElevation, cumulus.SolarOptions); if (!DataStopped) { @@ -12214,7 +12214,7 @@ public void UpdateAPRS() private string APRSLat(Cumulus cumulus) { string dir; - double lat; + decimal lat; int d, m, s; if (cumulus.Latitude < 0) { @@ -12242,7 +12242,7 @@ private string APRSLat(Cumulus cumulus) private string APRSLon(Cumulus cumulus) { string dir; - double lon; + decimal lon; int d, m, s; if (cumulus.Longitude < 0) { diff --git a/CumulusMX/Wizard.cs b/CumulusMX/Wizard.cs index 28621e38..e7125398 100644 --- a/CumulusMX/Wizard.cs +++ b/CumulusMX/Wizard.cs @@ -611,11 +611,11 @@ public string UpdateConfig(IHttpContext context) return context.Response.StatusCode == 200 ? "success" : errorMsg; } - private string degToString(double degrees, bool lat) + private string degToString(decimal degrees, bool lat) { var degs = (int)Math.Floor(Math.Abs(degrees)); - var minsF = (Math.Abs(degrees) - degs) * 60.0; - var secs = (int)Math.Round((minsF - Math.Floor(minsF)) * 60.0); + var minsF = (Math.Abs(degrees) - degs) * 60; + var secs = (int)Math.Round((minsF - Math.Floor(minsF)) * 60); var mins = (int)Math.Floor(minsF); string hemi; if (lat) @@ -639,8 +639,8 @@ internal class JsonWizard internal class JsonWizardLocation { - public double latitude { get; set; } - public double longitude { get; set; } + public decimal latitude { get; set; } + public decimal longitude { get; set; } public int altitude { get; set; } public string altitudeunit { get; set; } public string sitename { get; set; } diff --git a/CumulusMX/webtags.cs b/CumulusMX/webtags.cs index 5df517b9..ff2e2311 100644 --- a/CumulusMX/webtags.cs +++ b/CumulusMX/webtags.cs @@ -129,6 +129,30 @@ private static string CheckRcDp(double val, Dictionary tagParams } } + private static string CheckRcDp(decimal val, Dictionary tagParams, int decimals) + { + string ret; + try + { + if (tagParams.Get("tc") == "y") + return Math.Truncate(val).ToString(); + + int dp = int.TryParse(tagParams.Get("dp"), out dp) ? dp : decimals; + + ret = val.ToString("F" + dp); + + if (tagParams.Get("rc") == "y") + { + ret = ReplaceCommas(ret); + } + return ret; + } + catch + { + return "error"; + } + } + private double GetSnowDepth(DateTime day) { double depth; @@ -1027,7 +1051,7 @@ private string TagAirLinkTempIn(Dictionary tagParams) } private string TagAirLinkHumIn(Dictionary tagParams) { - return cumulus.airLinkDataIn == null ? "--" : CheckRcDp(cumulus.airLinkDataIn.humidity, tagParams, cumulus.HumDPlaces); + return cumulus.airLinkDataIn == null ? "--" : CheckRcDp((decimal) cumulus.airLinkDataIn.humidity, tagParams, cumulus.HumDPlaces); } private string TagAirLinkPm1In(Dictionary tagParams) { @@ -1090,7 +1114,7 @@ private string TagAirLinkTempOut(Dictionary tagParams) } private string TagAirLinkHumOut(Dictionary tagParams) { - return cumulus.airLinkDataOut == null ? "--" : CheckRcDp(cumulus.airLinkDataOut.humidity, tagParams, cumulus.HumDPlaces); + return cumulus.airLinkDataOut == null ? "--" : CheckRcDp((decimal) cumulus.airLinkDataOut.humidity, tagParams, cumulus.HumDPlaces); } private string TagAirLinkPm1Out(Dictionary tagParams) { diff --git a/Updates.txt b/Updates.txt index ec1f339c..eb3cd275 100644 --- a/Updates.txt +++ b/Updates.txt @@ -5,6 +5,9 @@ Fixed - Change the MySQL table updates to compare column names rather than simple counts - Fix the All Time, Monthly, This Year records editors not allowing 24 hour rain values to be changed +Changed +- The station latitude and longitude are now stored internally as decimal values. This means there will be no loss of precision when storing locations entered as decimal values via the + configuration wizard, or directly in the Cumulus.ini file 3.20.0 - b3202 —————————————— From 671117c844df796a1b3f65afd62d987df0440fc3 Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Wed, 24 Aug 2022 15:06:29 +0100 Subject: [PATCH 07/12] Add SMTP ignore certificate error option --- CumulusMX/Cumulus.cs | 3 +++ CumulusMX/EmailSender.cs | 6 ++++++ CumulusMX/InternetSettings.cs | 6 +++++- Updates.txt | 4 ++++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index d0f2404f..afe04ba7 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -26,6 +26,7 @@ using SQLite; using Renci.SshNet; using System.Collections.Concurrent; +using System.Security.Authentication; namespace CumulusMX { @@ -5255,6 +5256,7 @@ private void ReadIniFile() SmtpOptions.RequiresAuthentication = ini.GetValue("SMTP", "RequiresAuthentication", false); SmtpOptions.User = ini.GetValue("SMTP", "User", ""); SmtpOptions.Password = ini.GetValue("SMTP", "Password", ""); + SmtpOptions.IgnoreCertErrors = ini.GetValue("SMTP", "IgnoreCertErrors", false); // Growing Degree Days GrowingBase1 = ini.GetValue("GrowingDD", "BaseTemperature1", (Units.Temp == 0 ? 5.0 : 40.0)); @@ -6221,6 +6223,7 @@ internal void WriteIniFile() ini.SetValue("SMTP", "User", SmtpOptions.User); ini.SetValue("SMTP", "Password", SmtpOptions.Password); ini.SetValue("SMTP", "Logging", SmtpOptions.Logging); + ini.SetValue("SMTP", "IgnoreCertErrors", SmtpOptions.IgnoreCertErrors); // Growing Degree Days ini.SetValue("GrowingDD", "BaseTemperature1", GrowingBase1); diff --git a/CumulusMX/EmailSender.cs b/CumulusMX/EmailSender.cs index eb2f4a72..4a6d5497 100644 --- a/CumulusMX/EmailSender.cs +++ b/CumulusMX/EmailSender.cs @@ -57,6 +57,11 @@ public async void SendEmail(string[] to, string from, string subject, string mes using (SmtpClient client = cumulus.SmtpOptions.Logging ? new SmtpClient(new ProtocolLogger("MXdiags/smtp.log")) : new SmtpClient()) { + if (cumulus.SmtpOptions.IgnoreCertErrors) + { + client.ServerCertificateValidationCallback = (s, c, h, e) => true; + } + await client.ConnectAsync(cumulus.SmtpOptions.Server, cumulus.SmtpOptions.Port, (MailKit.Security.SecureSocketOptions)cumulus.SmtpOptions.SslOption); // Note: since we don't have an OAuth2 token, disable @@ -192,6 +197,7 @@ public class SmtpOptions public int SslOption; public bool RequiresAuthentication; public bool Logging; + public bool IgnoreCertErrors; } } } diff --git a/CumulusMX/InternetSettings.cs b/CumulusMX/InternetSettings.cs index 65e804f9..0864aeb3 100644 --- a/CumulusMX/InternetSettings.cs +++ b/CumulusMX/InternetSettings.cs @@ -6,6 +6,7 @@ using System.Web; using ServiceStack; using EmbedIO; +using static ServiceStack.Diagnostics.Events; namespace CumulusMX { @@ -269,6 +270,7 @@ public string UpdateConfig(IHttpContext context) cumulus.SmtpOptions.RequiresAuthentication = settings.emailsettings.authenticate; cumulus.SmtpOptions.User = settings.emailsettings.user; cumulus.SmtpOptions.Password = settings.emailsettings.password; + cumulus.SmtpOptions.IgnoreCertErrors = settings.emailsettings.ignorecerterrors; if (cumulus.emailer == null) { @@ -523,7 +525,8 @@ public string GetAlpacaFormData() ssloption = cumulus.SmtpOptions.SslOption, authenticate = cumulus.SmtpOptions.RequiresAuthentication, user = cumulus.SmtpOptions.User, - password = cumulus.SmtpOptions.Password + password = cumulus.SmtpOptions.Password, + ignorecerterrors = cumulus.SmtpOptions.IgnoreCertErrors }; var misc = new JsonInternetSettingsMisc() @@ -800,6 +803,7 @@ public class JsonEmailSettings public bool authenticate { get; set; } public string user { get; set; } public string password { get; set; } + public bool ignorecerterrors { get; set; } } public class JsonInternetSettingsMisc diff --git a/Updates.txt b/Updates.txt index eb3cd275..0e65fa06 100644 --- a/Updates.txt +++ b/Updates.txt @@ -5,10 +5,14 @@ Fixed - Change the MySQL table updates to compare column names rather than simple counts - Fix the All Time, Monthly, This Year records editors not allowing 24 hour rain values to be changed +New +- Adds a new option to the email server settings to ignore certificate errors + Changed - The station latitude and longitude are now stored internally as decimal values. This means there will be no loss of precision when storing locations entered as decimal values via the configuration wizard, or directly in the Cumulus.ini file + 3.20.0 - b3202 —————————————— Fixed From 649da73c7675fe19c4b4f73852c73123bf7aa36c Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Thu, 25 Aug 2022 11:21:18 +0100 Subject: [PATCH 08/12] More exception handling for local file copies --- CumulusMX/Cumulus.cs | 72 ++++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index afe04ba7..9b78dff4 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -1033,8 +1033,8 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) DecimalSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator; - LogMessage("Directory separator=[" + DirectorySeparator + "] Decimal separator=[" + DecimalSeparator + "] List separator=[" + ListSeparator + "]"); - LogMessage("Date separator=[" + CultureInfo.CurrentCulture.DateTimeFormat.DateSeparator + "] Time separator=[" + CultureInfo.CurrentCulture.DateTimeFormat.TimeSeparator + "]"); + LogMessage($"Directory separator=[{DirectorySeparator}] Decimal separator=[{DecimalSeparator}] List separator=[{ListSeparator}]"); + LogMessage($"Date separator=[{CultureInfo.CurrentCulture.DateTimeFormat.DateSeparator}] Time separator=[{CultureInfo.CurrentCulture.DateTimeFormat.TimeSeparator}]"); TimeZone localZone = TimeZone.CurrentTimeZone; DateTime now = DateTime.Now; @@ -8161,17 +8161,29 @@ public void DoHTMLFiles() public void DoLocalCopy() { var remotePath = ""; - var folderSep1 = Path.DirectorySeparatorChar.ToString(); - var folderSep2 = Path.AltDirectorySeparatorChar.ToString(); - if (!FtpOptions.LocalCopyEnabled) - return; + try + { + var folderSep2 = Path.AltDirectorySeparatorChar; - if (FtpOptions.LocalCopyFolder.Length > 0) + if (!FtpOptions.LocalCopyEnabled) + return; + + if (FtpOptions.LocalCopyFolder.Length > 0) + { + remotePath = (FtpOptions.LocalCopyFolder[-1] == DirectorySeparator || FtpOptions.LocalCopyFolder[-1] == folderSep2) ? FtpOptions.LocalCopyFolder : FtpOptions.LocalCopyFolder + DirectorySeparator; + } + else + { + return; + } + } + catch (Exception ex) { - remotePath = (FtpOptions.LocalCopyFolder.EndsWith(folderSep1) || FtpOptions.LocalCopyFolder.EndsWith(folderSep2) ? FtpOptions.LocalCopyFolder : FtpOptions.LocalCopyFolder + folderSep1); + LogMessage("LocalCopy: Error with paths - " + ex.Message); } + var srcfile = ""; string dstfile; @@ -8182,21 +8194,28 @@ public void DoLocalCopy() // upload NOAA reports LogDebugMessage("LocalCopy: Copying NOAA reports"); - var dstPath = string.IsNullOrEmpty(NOAAconf.CopyFolder) ? remotePath : NOAAconf.CopyFolder; + try + { + var dstPath = string.IsNullOrEmpty(NOAAconf.CopyFolder) ? remotePath : NOAAconf.CopyFolder; - srcfile = ReportPath + NOAAconf.LatestMonthReport; - dstfile = dstPath + folderSep1 + NOAAconf.LatestMonthReport; + srcfile = ReportPath + NOAAconf.LatestMonthReport; + dstfile = dstPath + DirectorySeparator + NOAAconf.LatestMonthReport; - File.Copy(srcfile, dstfile, true); + File.Copy(srcfile, dstfile, true); - srcfile = ReportPath + NOAAconf.LatestYearReport; - dstfile = dstPath + folderSep1 + NOAAconf.LatestYearReport; + srcfile = ReportPath + NOAAconf.LatestYearReport; + dstfile = dstPath + DirectorySeparator + NOAAconf.LatestYearReport; - File.Copy(srcfile, dstfile, true); + File.Copy(srcfile, dstfile, true); - NOAAconf.NeedCopy = false; + NOAAconf.NeedCopy = false; - LogDebugMessage("LocalCopy: Done copying NOAA reports"); + LogDebugMessage("LocalCopy: Done copying NOAA reports"); + } + catch (Exception ex) + { + LogMessage("LocalCopy: Error copy NOAA reports - " + ex.Message); + } } catch (Exception e) { @@ -8205,7 +8224,7 @@ public void DoLocalCopy() } // standard files - LogDebugMessage("LocalCopy: Uploading standard web files"); + LogDebugMessage("LocalCopy: Copying standard web files"); for (var i = 0; i < StdWebFiles.Length; i++) { if (StdWebFiles[i].Copy && StdWebFiles[i].CopyRequired) @@ -8219,7 +8238,7 @@ public void DoLocalCopy() catch (Exception e) { LogMessage($"LocalCopy: Error copying standard data file [{StdWebFiles[i].LocalFileName}]"); - LogMessage($"LocalCopy: Error = {e}"); + LogMessage($"LocalCopy: Error = {e.Message}"); } } } @@ -8230,11 +8249,11 @@ public void DoLocalCopy() { if (GraphDataFiles[i].Copy && GraphDataFiles[i].CopyRequired) { - srcfile = GraphDataFiles[i].LocalPath + GraphDataFiles[i].LocalFileName; - dstfile = remotePath + GraphDataFiles[i].RemoteFileName; - try { + srcfile = GraphDataFiles[i].LocalPath + GraphDataFiles[i].LocalFileName; + dstfile = remotePath + GraphDataFiles[i].RemoteFileName; + File.Copy(srcfile, dstfile, true); // The config files only need uploading once per change if (GraphDataFiles[i].LocalFileName == "availabledata.json" || @@ -8246,7 +8265,7 @@ public void DoLocalCopy() catch (Exception e) { LogMessage($"LocalCopy: Error copying graph data file [{srcfile}]"); - LogMessage($"LocalCopy: Error = {e}"); + LogMessage($"LocalCopy: Error = {e.Message}"); } } } @@ -8257,10 +8276,11 @@ public void DoLocalCopy() { if (GraphDataEodFiles[i].Copy && GraphDataEodFiles[i].CopyRequired) { - srcfile = GraphDataEodFiles[i].LocalPath + GraphDataEodFiles[i].LocalFileName; - dstfile = remotePath + GraphDataEodFiles[i].RemoteFileName; try { + srcfile = GraphDataEodFiles[i].LocalPath + GraphDataEodFiles[i].LocalFileName; + dstfile = remotePath + GraphDataEodFiles[i].RemoteFileName; + File.Copy(srcfile, dstfile, true); // Uploaded OK, reset the upload required flag GraphDataEodFiles[i].CopyRequired = false; @@ -8268,7 +8288,7 @@ public void DoLocalCopy() catch (Exception e) { LogMessage($"LocalCopy: Error copying daily graph data file [{srcfile}]"); - LogMessage($"LocalCopy: Error = {e}"); + LogMessage($"LocalCopy: Error = {e.Message}"); } } } From 10d1e1eb21d5f4a23aef475d9a0abbf52fc30901 Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Thu, 25 Aug 2022 11:28:12 +0100 Subject: [PATCH 09/12] Add missing extra columns to update MySQL on dayfile edit --- CumulusMX/DataEditor.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CumulusMX/DataEditor.cs b/CumulusMX/DataEditor.cs index 57988e09..20652fb6 100644 --- a/CumulusMX/DataEditor.cs +++ b/CumulusMX/DataEditor.cs @@ -3377,7 +3377,10 @@ internal string EditDayFile(IHttpContext context) updt.Append($"MinFeelsLike={station.DayFile[lineNum].LowFeelsLike.ToString(cumulus.TempFormat, InvC)},"); updt.Append($"TMinFeelsLike={station.DayFile[lineNum].LowFeelsLikeTime:\\'HH:mm\\'},"); updt.Append($"MaxHumidex={station.DayFile[lineNum].HighHumidex.ToString(cumulus.TempFormat, InvC)},"); - updt.Append($"TMaxHumidex={station.DayFile[lineNum].HighFeelsLikeTime:\\'HH:mm\\'} "); + updt.Append($"TMaxHumidex={station.DayFile[lineNum].HighFeelsLikeTime:\\'HH:mm\\'},"); + updt.Append($"ChillHours={station.DayFile[lineNum].ChillHours.ToString("F1", InvC)},"); + updt.Append($"HighRain24h={station.DayFile[lineNum].HighRain24h.ToString(cumulus.RainFormat, InvC)},"); + updt.Append($"THighRain24h={station.DayFile[lineNum].HighRain24hTime:\\'HH:mm\\'} "); updt.Append($"WHERE LogDate='{station.DayFile[lineNum].Date:yyyy-MM-dd}';"); updateStr = updt.ToString(); From 1ca49d8758dd839d226486c93c1d73e2e2266ee0 Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Thu, 25 Aug 2022 13:52:11 +0100 Subject: [PATCH 10/12] Fix Dayfile editor inserting 9999/-9999 values into the MySQL database when values are missing --- CumulusMX/DataEditor.cs | 50 ++++++++++++++++++++--------------------- Updates.txt | 2 ++ 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/CumulusMX/DataEditor.cs b/CumulusMX/DataEditor.cs index 20652fb6..feb416c0 100644 --- a/CumulusMX/DataEditor.cs +++ b/CumulusMX/DataEditor.cs @@ -3343,26 +3343,26 @@ internal string EditDayFile(IHttpContext context) updt.Append($"TotWindRun={station.DayFile[lineNum].WindRun.ToString("F1", InvC)},"); 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},"); - updt.Append($"TLowHum={station.DayFile[lineNum].LowHumidityTime:\\'HH:mm\\'},"); - updt.Append($"HighHum={station.DayFile[lineNum].HighHumidity},"); - updt.Append($"THighHum={station.DayFile[lineNum].HighHumidityTime:\\'HH:mm\\'},"); + updt.Append($"LowHum={(station.DayFile[lineNum].LowHumidity < 9999 ? station.DayFile[lineNum].LowHumidity.ToString() : "null")},"); + updt.Append($"TLowHum={(station.DayFile[lineNum].LowHumidity < 9999 ? station.DayFile[lineNum].LowHumidityTime.ToString("HH:mm") : "null")},"); + updt.Append($"HighHum={(station.DayFile[lineNum].HighHumidity > -9999 ? station.DayFile[lineNum].HighHumidity.ToString() : "null")},"); + updt.Append($"THighHum={(station.DayFile[lineNum].HighHumidity > -9999 ? 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.ToString(cumulus.TempFormat, InvC)},"); - updt.Append($"THighHeatInd={station.DayFile[lineNum].HighHeatIndexTime:\\'HH:mm\\'},"); - updt.Append($"HighAppTemp={station.DayFile[lineNum].HighAppTemp.ToString(cumulus.TempFormat, InvC)},"); - updt.Append($"THighAppTemp={station.DayFile[lineNum].HighAppTempTime:\\'HH:mm\\'},"); - updt.Append($"LowAppTemp={station.DayFile[lineNum].LowAppTemp.ToString(cumulus.TempFormat, InvC)},"); - updt.Append($"TLowAppTemp={station.DayFile[lineNum].LowAppTempTime:\\'HH:mm\\'},"); + updt.Append($"HighHeatInd={(station.DayFile[lineNum].HighHeatIndex > -9999 ? station.DayFile[lineNum].HighHeatIndex.ToString(cumulus.TempFormat, InvC) : "null")},"); + updt.Append($"THighHeatInd={(station.DayFile[lineNum].HighHeatIndex > -9999 ? station.DayFile[lineNum].HighHeatIndexTime.ToString("HH:mm") : "null")},"); + updt.Append($"HighAppTemp={(station.DayFile[lineNum].HighAppTemp > -9999 ? station.DayFile[lineNum].HighAppTemp.ToString(cumulus.TempFormat, InvC) : "null")},"); + updt.Append($"THighAppTemp={(station.DayFile[lineNum].HighAppTemp > -9999 ? station.DayFile[lineNum].HighAppTempTime.ToString("HH:mm") : "null")},"); + updt.Append($"LowAppTemp={(station.DayFile[lineNum].LowAppTemp < 9999 ? station.DayFile[lineNum].LowAppTemp.ToString(cumulus.TempFormat, InvC) : "null")},"); + updt.Append($"TLowAppTemp={(station.DayFile[lineNum].LowAppTemp < 9999 ? 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.ToString(cumulus.TempFormat, InvC)},"); - updt.Append($"TLowWindChill={station.DayFile[lineNum].LowWindChillTime:\\'HH:mm\\'},"); - updt.Append($"HighDewPoint={station.DayFile[lineNum].HighDewPoint.ToString(cumulus.TempFormat, InvC)},"); - updt.Append($"THighDewPoint={station.DayFile[lineNum].HighDewPointTime:\\'HH:mm\\'},"); - updt.Append($"LowDewPoint={station.DayFile[lineNum].LowDewPoint.ToString(cumulus.TempFormat, InvC)},"); - updt.Append($"TLowDewPoint={station.DayFile[lineNum].LowDewPointTime:\\'HH:mm\\'},"); + updt.Append($"LowWindChill={(station.DayFile[lineNum].LowWindChill < 9999 ? station.DayFile[lineNum].LowWindChill.ToString(cumulus.TempFormat, InvC) : "null")},"); + updt.Append($"TLowWindChill={(station.DayFile[lineNum].LowWindChill < 9999 ? station.DayFile[lineNum].LowWindChillTime.ToString("HH:mm") : "null")},"); + updt.Append($"HighDewPoint={(station.DayFile[lineNum].HighDewPoint > -9999 ? station.DayFile[lineNum].HighDewPoint.ToString(cumulus.TempFormat, InvC) : "null")},"); + updt.Append($"THighDewPoint={(station.DayFile[lineNum].HighDewPoint > -9999 ? station.DayFile[lineNum].HighDewPointTime.ToString("HH:mm") : "null")},"); + updt.Append($"LowDewPoint={(station.DayFile[lineNum].LowDewPoint < 9999 ? station.DayFile[lineNum].LowDewPoint.ToString(cumulus.TempFormat, InvC) : "null")},"); + updt.Append($"TLowDewPoint={(station.DayFile[lineNum].LowDewPoint < 9999 ? station.DayFile[lineNum].LowDewPointTime.ToString("HH:mm") : "null")},"); updt.Append($"DomWindDir={station.DayFile[lineNum].DominantWindBearing},"); updt.Append($"HeatDegDays={station.DayFile[lineNum].HeatingDegreeDays.ToString("F1", InvC)},"); updt.Append($"CoolDegDays={station.DayFile[lineNum].CoolingDegreeDays.ToString("F1", InvC)},"); @@ -3372,15 +3372,15 @@ internal string EditDayFile(IHttpContext context) updt.Append($"THighUV={station.DayFile[lineNum].HighUvTime:\\'HH:mm\\'},"); 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.ToString(cumulus.TempFormat, InvC)},"); - updt.Append($"TMaxFeelsLike={station.DayFile[lineNum].HighFeelsLikeTime:\\'HH:mm\\'},"); - updt.Append($"MinFeelsLike={station.DayFile[lineNum].LowFeelsLike.ToString(cumulus.TempFormat, InvC)},"); - updt.Append($"TMinFeelsLike={station.DayFile[lineNum].LowFeelsLikeTime:\\'HH:mm\\'},"); - updt.Append($"MaxHumidex={station.DayFile[lineNum].HighHumidex.ToString(cumulus.TempFormat, InvC)},"); - updt.Append($"TMaxHumidex={station.DayFile[lineNum].HighFeelsLikeTime:\\'HH:mm\\'},"); - updt.Append($"ChillHours={station.DayFile[lineNum].ChillHours.ToString("F1", InvC)},"); - updt.Append($"HighRain24h={station.DayFile[lineNum].HighRain24h.ToString(cumulus.RainFormat, InvC)},"); - updt.Append($"THighRain24h={station.DayFile[lineNum].HighRain24hTime:\\'HH:mm\\'} "); + updt.Append($"MaxFeelsLike={(station.DayFile[lineNum].HighFeelsLike > -9999 ? station.DayFile[lineNum].HighFeelsLike.ToString(cumulus.TempFormat, InvC) : "null")},"); + updt.Append($"TMaxFeelsLike={(station.DayFile[lineNum].HighFeelsLike > -9999 ? station.DayFile[lineNum].HighFeelsLikeTime.ToString("HH:mm") : "null")},"); + updt.Append($"MinFeelsLike={(station.DayFile[lineNum].LowFeelsLike < 9999 ? station.DayFile[lineNum].LowFeelsLike.ToString(cumulus.TempFormat, InvC) : "null")},"); + updt.Append($"TMinFeelsLike={(station.DayFile[lineNum].LowFeelsLike < 9999 ? station.DayFile[lineNum].LowFeelsLikeTime.ToString("HH:mm") : "null")},"); + updt.Append($"MaxHumidex={(station.DayFile[lineNum].HighHumidex > -9999 ? station.DayFile[lineNum].HighHumidex.ToString(cumulus.TempFormat, InvC) : "null")},"); + updt.Append($"TMaxHumidex={(station.DayFile[lineNum].HighHumidex > -9999 ? station.DayFile[lineNum].HighHumidexTime.ToString("HH:mm") : "null")},"); + updt.Append($"ChillHours={(station.DayFile[lineNum].ChillHours > -9999 ? station.DayFile[lineNum].ChillHours.ToString("F1", InvC) : "null")},"); + updt.Append($"HighRain24h={(station.DayFile[lineNum].HighRain24h > -9999 ? station.DayFile[lineNum].HighRain24h.ToString(cumulus.RainFormat, InvC) : "null")},"); + updt.Append($"THighRain24h={(station.DayFile[lineNum].HighRain24h > -9999 ? station.DayFile[lineNum].HighRain24hTime.ToString("HH:mm") : "null")} "); updt.Append($"WHERE LogDate='{station.DayFile[lineNum].Date:yyyy-MM-dd}';"); updateStr = updt.ToString(); diff --git a/Updates.txt b/Updates.txt index 0e65fa06..3275903c 100644 --- a/Updates.txt +++ b/Updates.txt @@ -4,6 +4,8 @@ Fixed - Fix crash in Alarms with some station types - Change the MySQL table updates to compare column names rather than simple counts - Fix the All Time, Monthly, This Year records editors not allowing 24 hour rain values to be changed +- Fix Dayfile editor not updating ChillHours and 24 hour rainfall values in the MySQL database +- Fix Dayfile editor inserting 9999/-9999 values into the MySQL database when values are missing New - Adds a new option to the email server settings to ignore certificate errors From 7c9e0d927d5d07ee37c576e5b0de3c0506c6eb1a Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Thu, 25 Aug 2022 13:52:11 +0100 Subject: [PATCH 11/12] Fix Dayfile editor inserting 9999/-9999 values into the MySQL database when values are missing --- CumulusMX/DataEditor.cs | 50 ++++++++++++++++++++--------------------- Updates.txt | 2 ++ 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/CumulusMX/DataEditor.cs b/CumulusMX/DataEditor.cs index 20652fb6..b5e8e241 100644 --- a/CumulusMX/DataEditor.cs +++ b/CumulusMX/DataEditor.cs @@ -3343,26 +3343,26 @@ internal string EditDayFile(IHttpContext context) updt.Append($"TotWindRun={station.DayFile[lineNum].WindRun.ToString("F1", InvC)},"); 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},"); - updt.Append($"TLowHum={station.DayFile[lineNum].LowHumidityTime:\\'HH:mm\\'},"); - updt.Append($"HighHum={station.DayFile[lineNum].HighHumidity},"); - updt.Append($"THighHum={station.DayFile[lineNum].HighHumidityTime:\\'HH:mm\\'},"); + updt.Append($"LowHum={(station.DayFile[lineNum].LowHumidity < 9999 ? station.DayFile[lineNum].LowHumidity.ToString() : "NULL")},"); + updt.Append($"TLowHum={(station.DayFile[lineNum].LowHumidity < 9999 ? $"'{station.DayFile[lineNum].LowHumidityTime.ToString("HH:mm")}'" : "NULL")},"); + updt.Append($"HighHum={(station.DayFile[lineNum].HighHumidity > -9999 ? station.DayFile[lineNum].HighHumidity.ToString() : "NULL")},"); + updt.Append($"THighHum={(station.DayFile[lineNum].HighHumidity > -9999 ? $"'{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.ToString(cumulus.TempFormat, InvC)},"); - updt.Append($"THighHeatInd={station.DayFile[lineNum].HighHeatIndexTime:\\'HH:mm\\'},"); - updt.Append($"HighAppTemp={station.DayFile[lineNum].HighAppTemp.ToString(cumulus.TempFormat, InvC)},"); - updt.Append($"THighAppTemp={station.DayFile[lineNum].HighAppTempTime:\\'HH:mm\\'},"); - updt.Append($"LowAppTemp={station.DayFile[lineNum].LowAppTemp.ToString(cumulus.TempFormat, InvC)},"); - updt.Append($"TLowAppTemp={station.DayFile[lineNum].LowAppTempTime:\\'HH:mm\\'},"); + updt.Append($"HighHeatInd={(station.DayFile[lineNum].HighHeatIndex > -9999 ? station.DayFile[lineNum].HighHeatIndex.ToString(cumulus.TempFormat, InvC) : "NULL")},"); + updt.Append($"THighHeatInd={(station.DayFile[lineNum].HighHeatIndex > -9999 ? $"'{station.DayFile[lineNum].HighHeatIndexTime.ToString("HH:mm")}'" : "NULL")},"); + updt.Append($"HighAppTemp={(station.DayFile[lineNum].HighAppTemp > -9999 ? station.DayFile[lineNum].HighAppTemp.ToString(cumulus.TempFormat, InvC) : "NULL")},"); + updt.Append($"THighAppTemp={(station.DayFile[lineNum].HighAppTemp > -9999 ? $"'{station.DayFile[lineNum].HighAppTempTime.ToString("HH:mm")}'" : "NULL")},"); + updt.Append($"LowAppTemp={(station.DayFile[lineNum].LowAppTemp < 9999 ? station.DayFile[lineNum].LowAppTemp.ToString(cumulus.TempFormat, InvC) : "NULL")},"); + updt.Append($"TLowAppTemp={(station.DayFile[lineNum].LowAppTemp < 9999 ? $"'{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.ToString(cumulus.TempFormat, InvC)},"); - updt.Append($"TLowWindChill={station.DayFile[lineNum].LowWindChillTime:\\'HH:mm\\'},"); - updt.Append($"HighDewPoint={station.DayFile[lineNum].HighDewPoint.ToString(cumulus.TempFormat, InvC)},"); - updt.Append($"THighDewPoint={station.DayFile[lineNum].HighDewPointTime:\\'HH:mm\\'},"); - updt.Append($"LowDewPoint={station.DayFile[lineNum].LowDewPoint.ToString(cumulus.TempFormat, InvC)},"); - updt.Append($"TLowDewPoint={station.DayFile[lineNum].LowDewPointTime:\\'HH:mm\\'},"); + updt.Append($"LowWindChill={(station.DayFile[lineNum].LowWindChill < 9999 ? station.DayFile[lineNum].LowWindChill.ToString(cumulus.TempFormat, InvC) : "NULL")},"); + updt.Append($"TLowWindChill={(station.DayFile[lineNum].LowWindChill < 9999 ? $"'{station.DayFile[lineNum].LowWindChillTime.ToString("HH:mm")}'" : "NULL")},"); + updt.Append($"HighDewPoint={(station.DayFile[lineNum].HighDewPoint > -9999 ? station.DayFile[lineNum].HighDewPoint.ToString(cumulus.TempFormat, InvC) : "NULL")},"); + updt.Append($"THighDewPoint={(station.DayFile[lineNum].HighDewPoint > -9999 ? $"'{station.DayFile[lineNum].HighDewPointTime.ToString("HH:mm")}'" : "NULL")},"); + updt.Append($"LowDewPoint={(station.DayFile[lineNum].LowDewPoint < 9999 ? station.DayFile[lineNum].LowDewPoint.ToString(cumulus.TempFormat, InvC) : "NULL")},"); + updt.Append($"TLowDewPoint={(station.DayFile[lineNum].LowDewPoint < 9999 ? $"'{station.DayFile[lineNum].LowDewPointTime.ToString("HH:mm")}'" : "NULL")},"); updt.Append($"DomWindDir={station.DayFile[lineNum].DominantWindBearing},"); updt.Append($"HeatDegDays={station.DayFile[lineNum].HeatingDegreeDays.ToString("F1", InvC)},"); updt.Append($"CoolDegDays={station.DayFile[lineNum].CoolingDegreeDays.ToString("F1", InvC)},"); @@ -3372,15 +3372,15 @@ internal string EditDayFile(IHttpContext context) updt.Append($"THighUV={station.DayFile[lineNum].HighUvTime:\\'HH:mm\\'},"); 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.ToString(cumulus.TempFormat, InvC)},"); - updt.Append($"TMaxFeelsLike={station.DayFile[lineNum].HighFeelsLikeTime:\\'HH:mm\\'},"); - updt.Append($"MinFeelsLike={station.DayFile[lineNum].LowFeelsLike.ToString(cumulus.TempFormat, InvC)},"); - updt.Append($"TMinFeelsLike={station.DayFile[lineNum].LowFeelsLikeTime:\\'HH:mm\\'},"); - updt.Append($"MaxHumidex={station.DayFile[lineNum].HighHumidex.ToString(cumulus.TempFormat, InvC)},"); - updt.Append($"TMaxHumidex={station.DayFile[lineNum].HighFeelsLikeTime:\\'HH:mm\\'},"); - updt.Append($"ChillHours={station.DayFile[lineNum].ChillHours.ToString("F1", InvC)},"); - updt.Append($"HighRain24h={station.DayFile[lineNum].HighRain24h.ToString(cumulus.RainFormat, InvC)},"); - updt.Append($"THighRain24h={station.DayFile[lineNum].HighRain24hTime:\\'HH:mm\\'} "); + updt.Append($"MaxFeelsLike={(station.DayFile[lineNum].HighFeelsLike > -9999 ? station.DayFile[lineNum].HighFeelsLike.ToString(cumulus.TempFormat, InvC) : "NULL")},"); + updt.Append($"TMaxFeelsLike={(station.DayFile[lineNum].HighFeelsLike > -9999 ? $"'{station.DayFile[lineNum].HighFeelsLikeTime.ToString("HH:mm")}'" : "NULL")},"); + updt.Append($"MinFeelsLike={(station.DayFile[lineNum].LowFeelsLike < 9999 ? station.DayFile[lineNum].LowFeelsLike.ToString(cumulus.TempFormat, InvC) : "NULL")},"); + updt.Append($"TMinFeelsLike={(station.DayFile[lineNum].LowFeelsLike < 9999 ? $"'{station.DayFile[lineNum].LowFeelsLikeTime.ToString("HH:mm")}'" : "NULL")},"); + updt.Append($"MaxHumidex={(station.DayFile[lineNum].HighHumidex > -9999 ? station.DayFile[lineNum].HighHumidex.ToString(cumulus.TempFormat, InvC) : "NULL")},"); + updt.Append($"TMaxHumidex={(station.DayFile[lineNum].HighHumidex > -9999 ? $"'{station.DayFile[lineNum].HighHumidexTime.ToString("HH:mm")}'" : "NULL")},"); + updt.Append($"ChillHours={(station.DayFile[lineNum].ChillHours > -9999 ? station.DayFile[lineNum].ChillHours.ToString("F1", InvC) : "NULL")},"); + updt.Append($"HighRain24h={(station.DayFile[lineNum].HighRain24h > -9999 ? station.DayFile[lineNum].HighRain24h.ToString(cumulus.RainFormat, InvC) : "NULL")},"); + updt.Append($"THighRain24h={(station.DayFile[lineNum].HighRain24h > -9999 ? $"'{station.DayFile[lineNum].HighRain24hTime.ToString("HH:mm")}'" : "NULL")} "); updt.Append($"WHERE LogDate='{station.DayFile[lineNum].Date:yyyy-MM-dd}';"); updateStr = updt.ToString(); diff --git a/Updates.txt b/Updates.txt index 0e65fa06..3275903c 100644 --- a/Updates.txt +++ b/Updates.txt @@ -4,6 +4,8 @@ Fixed - Fix crash in Alarms with some station types - Change the MySQL table updates to compare column names rather than simple counts - Fix the All Time, Monthly, This Year records editors not allowing 24 hour rain values to be changed +- Fix Dayfile editor not updating ChillHours and 24 hour rainfall values in the MySQL database +- Fix Dayfile editor inserting 9999/-9999 values into the MySQL database when values are missing New - Adds a new option to the email server settings to ignore certificate errors From 963d21df4ea43d3bfe6f885f2392b441cdf155f8 Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Sun, 28 Aug 2022 22:40:14 +0100 Subject: [PATCH 12/12] Don't cache MySQL errors on duplicate keys --- CumulusMX/Cumulus.cs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index 9b78dff4..2d4e99b6 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -10335,17 +10335,18 @@ public void MySqlCommandSync(ConcurrentQueue Cmds, string CallingFunctio internal void MySqlCommandErrorHandler(string CallingFunction, int ErrorCode, ConcurrentQueue Cmds) { - var ignore = ErrorCode == (int) MySqlConnector.MySqlErrorCode.ParseError || - ErrorCode == (int) MySqlConnector.MySqlErrorCode.EmptyQuery || - ErrorCode == (int) MySqlConnector.MySqlErrorCode.TooBigSelect || - ErrorCode == (int) MySqlConnector.MySqlErrorCode.InvalidUseOfNull || - ErrorCode == (int) MySqlConnector.MySqlErrorCode.MixOfGroupFunctionAndFields || - ErrorCode == (int) MySqlConnector.MySqlErrorCode.SyntaxError || - ErrorCode == (int) MySqlConnector.MySqlErrorCode.TooLongString || - ErrorCode == (int) MySqlConnector.MySqlErrorCode.WrongColumnName || - ErrorCode == (int) MySqlConnector.MySqlErrorCode.DuplicateUnique || - ErrorCode == (int) MySqlConnector.MySqlErrorCode.PrimaryCannotHaveNull || - ErrorCode == (int) MySqlConnector.MySqlErrorCode.DivisionByZero; + var ignore = ErrorCode == (int) MySqlErrorCode.ParseError || + ErrorCode == (int) MySqlErrorCode.EmptyQuery || + ErrorCode == (int) MySqlErrorCode.TooBigSelect || + ErrorCode == (int) MySqlErrorCode.InvalidUseOfNull || + ErrorCode == (int) MySqlErrorCode.MixOfGroupFunctionAndFields || + ErrorCode == (int) MySqlErrorCode.SyntaxError || + ErrorCode == (int) MySqlErrorCode.TooLongString || + ErrorCode == (int) MySqlErrorCode.WrongColumnName || + ErrorCode == (int) MySqlErrorCode.DuplicateUnique || + ErrorCode == (int) MySqlErrorCode.PrimaryCannotHaveNull || + ErrorCode == (int) MySqlErrorCode.DivisionByZero || + ErrorCode == (int) MySqlErrorCode.DuplicateKeyEntry; if (ignore) {