From fa4a9eb80750553187d3a80725085e588e500d52 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Tue, 23 Jul 2024 16:06:41 +0100 Subject: [PATCH 01/13] Package Updates - SixLabors.ImageSharp - FluentFTP - MailKit - NReco.Logging.File - ServiceStack.Text - SSH.Net --- CumulusMX/CumulusMX.csproj | 12 ++++++------ Updates.txt | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/CumulusMX/CumulusMX.csproj b/CumulusMX/CumulusMX.csproj index bccd6311..17fdfa66 100644 --- a/CumulusMX/CumulusMX.csproj +++ b/CumulusMX/CumulusMX.csproj @@ -36,7 +36,7 @@ - 4.1.2.4027 + 4.1.3.4028 Copyright © 2015-$([System.DateTime]::Now.ToString('yyyy')) Cumulus MX @@ -69,19 +69,19 @@ - + - + - + - - + + diff --git a/Updates.txt b/Updates.txt index 26e80c95..54dd6965 100644 --- a/Updates.txt +++ b/Updates.txt @@ -1,3 +1,19 @@ + +4.1.3 - b4028 +————————————— +New +Changed +Fixed + +Package Updates +- SixLabors.ImageSharp +- FluentFTP +- MailKit +- NReco.Logging.File +- ServiceStack.Text +- SSH.Net + + 4.1.2 - b4027 ————————————— New From 42d811c0bdfad45fd802c8b41a9a021c5b914c3b Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Tue, 23 Jul 2024 17:28:50 +0100 Subject: [PATCH 02/13] Fix the Cumulus MX version comparison with latest online at startup and daily --- CumulusMX/Cumulus.cs | 85 ++++++++++++++++++++++++++++---------------- Updates.txt | 5 +++ 2 files changed, 60 insertions(+), 30 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index 64bdd82d..82b42eb9 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -46,7 +46,6 @@ using Swan; -using static System.Net.WebRequestMethods; using static CumulusMX.EmailSender; using File = System.IO.File; @@ -12908,10 +12907,10 @@ public async Task GetLatestVersion() var body = await retval.Content.ReadAsStringAsync(); var releases = body.FromJson>(); - var latestBuild = releases.Find(x => !x.draft && x.prerelease == beta); + var latestBeta = releases.Find(x => !x.draft && x.prerelease); var latestLive = releases.Find(x => !x.draft && !x.prerelease); var cmxBuild = int.Parse(Build); - var veryLatest = Math.Max(int.Parse(latestBuild.tag_name[1..]), int.Parse(latestLive.tag_name[1..])); + var veryLatest = Math.Max(int.Parse(latestBeta.tag_name[1..]), int.Parse(latestLive.tag_name[1..])); if (string.IsNullOrEmpty(latestLive.name)) { @@ -12919,39 +12918,65 @@ public async Task GetLatestVersion() { LogMessage("Failed to get the latest build version from GitHub"); } + return; } - else if (string.IsNullOrEmpty(latestBuild.name)) - { - LogMessage($"Failed to get the latest {(beta ? "beta" : "release")} build version from GitHub"); - } - else if (beta && int.Parse(latestLive.tag_name[1..]) > cmxBuild) - { - var msg = $"You are running a beta version of Cumulus MX, and a later release build {latestLive.name} is available."; - LogConsoleMessage(msg, ConsoleColor.Cyan); - LogWarningMessage(msg); - UpgradeAlarm.LastMessage = $"Release build {latestLive.name} is available"; - UpgradeAlarm.Triggered = true; - LatestBuild = latestLive.tag_name[1..]; - } - else if (int.Parse(latestBuild.tag_name[1..]) > cmxBuild) + else if (string.IsNullOrEmpty(latestBeta.name)) { - var msg = $"You are not running the latest {(beta ? "beta" : "release")} version of Cumulus MX, build {latestBuild.name} is available."; - LogConsoleMessage(msg, ConsoleColor.Cyan); - LogWarningMessage(msg); - UpgradeAlarm.LastMessage = $"{(beta ? "Beta" : "Release")} build {latestBuild.name} is available"; - UpgradeAlarm.Triggered = true; - LatestBuild = latestBuild.tag_name[1..]; + LogMessage("Failed to get the latest beta build version from GitHub"); + return; } - else if (int.Parse(latestBuild.tag_name[1..]) == cmxBuild) + + if (beta) { - LogMessage($"This Cumulus MX instance is running the latest {(beta ? "beta" : "release")} version"); - UpgradeAlarm.Triggered = false; - LatestBuild = latestBuild.tag_name[1..]; + if (int.Parse(latestLive.tag_name[1..]) > cmxBuild) + { + var msg = $"You are running a beta version of Cumulus MX, and a later release build {latestLive.name} is available."; + LogConsoleMessage(msg, ConsoleColor.Cyan); + LogWarningMessage(msg); + UpgradeAlarm.LastMessage = $"Release build {latestLive.name} is available"; + UpgradeAlarm.Triggered = true; + LatestBuild = latestLive.tag_name[1..]; + } + else if (int.Parse(latestBeta.tag_name[1..]) == cmxBuild) + { + LogMessage($"This Cumulus MX instance is running the latest beta version"); + UpgradeAlarm.Triggered = false; + LatestBuild = latestLive.tag_name[1..]; + } + else if (int.Parse(latestBeta.tag_name[1..]) > cmxBuild) + { + LogMessage($"This Cumulus MX beta instance is not running the latest beta version of Cumulsus MX, build {latestBeta.name} is available."); + UpgradeAlarm.Triggered = false; + LatestBuild = latestLive.tag_name[1..]; + } + else + { + LogWarningMessage($"This Cumulus MX instance appears to be running a beta test version. This build={Build}, latest available build={veryLatest}"); + LatestBuild = veryLatest.ToString(); + } } - else if (int.Parse(latestBuild.tag_name[1..]) < cmxBuild) + else // Live release { - LogWarningMessage($"This Cumulus MX instance appears to be running a test version. This build={Build}, latest available build={veryLatest}"); - LatestBuild = veryLatest.ToString(); + if (int.Parse(latestLive.tag_name[1..]) > cmxBuild) + { + var msg = $"You are not running the latest version of Cumulus MX, build {latestLive.name} is available."; + LogConsoleMessage(msg, ConsoleColor.Cyan); + LogWarningMessage(msg); + UpgradeAlarm.LastMessage = $"Release build {latestLive.name} is available"; + UpgradeAlarm.Triggered = true; + LatestBuild = latestBeta.tag_name[1..]; + } + else if (int.Parse(latestLive.tag_name[1..]) == cmxBuild) + { + LogMessage($"This Cumulus MX instance is running the latest release version"); + UpgradeAlarm.Triggered = false; + LatestBuild = latestBeta.tag_name[1..]; + } + else + { + LogWarningMessage($"This Cumulus MX instance appears to be running a test version. This build={Build}, latest available build={veryLatest}"); + LatestBuild = veryLatest.ToString(); + } } } catch (Exception ex) diff --git a/Updates.txt b/Updates.txt index 54dd6965..187754b6 100644 --- a/Updates.txt +++ b/Updates.txt @@ -2,8 +2,12 @@ 4.1.3 - b4028 ————————————— New + Changed + Fixed +- The Cumulus MX version comparison with latest online at startup and daily + Package Updates - SixLabors.ImageSharp @@ -14,6 +18,7 @@ Package Updates - SSH.Net + 4.1.2 - b4027 ————————————— New From ecba7364d4b713870a369989b2d94ad556bd4299 Mon Sep 17 00:00:00 2001 From: mcrossley <1196094+mcrossley@users.noreply.github.com> Date: Tue, 23 Jul 2024 19:11:38 +0100 Subject: [PATCH 03/13] Make zipping operation in memory --- CumulusMX/Cumulus.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index 82b42eb9..6b3e24c4 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -11139,17 +11139,17 @@ private async Task UploadString(HttpClient httpclient, bool incremental, s if (FtpOptions.PhpCompression == "gzip") { using var zipped = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Compress, true); - await zipped.WriteAsync(byteData, 0, byteData.Length, cancellationToken); + await zipped.WriteAsync(byteData.AsMemory(0, byteData.Length), cancellationToken); } else if (FtpOptions.PhpCompression == "deflate") { using var zipped = new System.IO.Compression.DeflateStream(ms, System.IO.Compression.CompressionMode.Compress, true); - await zipped.WriteAsync(byteData, 0, byteData.Length, cancellationToken); + await zipped.WriteAsync(byteData.AsMemory(0, byteData.Length), cancellationToken); } ms.Position = 0; byte[] compressed = new byte[ms.Length]; - await ms.ReadAsync(compressed, 0, compressed.Length, cancellationToken); + await ms.ReadAsync(compressed.AsMemory(0, compressed.Length), cancellationToken); outStream = new MemoryStream(compressed); streamContent = new StreamContent(outStream); From 31cc2590f05ec78e06172ed765be31926e7d7005 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Thu, 1 Aug 2024 14:22:12 +0100 Subject: [PATCH 04/13] Davis Cloud Station can now accurately determine the current conditions update rate Fix Davis WLL (and others) creating erroneous wind speed spike warnings --- CumulusMX/DavisCloudStation.cs | 17 ++++++++++++++++- CumulusMX/WeatherLinkDotCom.cs | 4 ++++ CumulusMX/WeatherStation.cs | 28 ++++++++++++++++++++++++++-- Updates.txt | 2 ++ 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/CumulusMX/DavisCloudStation.cs b/CumulusMX/DavisCloudStation.cs index 2e74d39d..f5ca15b4 100644 --- a/CumulusMX/DavisCloudStation.cs +++ b/CumulusMX/DavisCloudStation.cs @@ -3652,6 +3652,7 @@ private void GetAvailableStationIds(bool logToConsole = false) var stationsUrl = "https://api.weatherlink.com/v2/stations?api-key=" + cumulus.WllApiKey; cumulus.LogDebugMessage($"GetStations: URL = {stationsUrl.ToString().Replace(cumulus.WllApiKey, "API_KEY")}"); + cumulus.LogDebugMessage($"GetStations: Looking for station id = {cumulus.WllStationId}"); try { @@ -3697,7 +3698,7 @@ private void GetAvailableStationIds(bool logToConsole = false) } wlStationArchiveInterval = station.recording_interval; - DataTimeoutMins = wlStationArchiveInterval + 3; + SetDataTimeout(station.subscription_type); } } if (stationsObj.stations.Count > 1 && cumulus.WllStationId < 10) @@ -3715,6 +3716,7 @@ private void GetAvailableStationIds(bool logToConsole = false) cumulus.LogDebugMessage($"GetStations: Setting WLL parent ID = {stationsObj.stations[0].gateway_id}"); cumulus.WllParentId = stationsObj.stations[0].gateway_id; wlStationArchiveInterval = stationsObj.stations[0].recording_interval; + SetDataTimeout(stationsObj.stations[0].subscription_type); return; } } @@ -3724,6 +3726,19 @@ private void GetAvailableStationIds(bool logToConsole = false) } } + private void SetDataTimeout(string subscription) + { + subscription = (subscription ?? "basic").ToLower(); + + DataTimeoutMins = subscription switch + { + "basic" => 15 + 3, + "pro" => 5 + 3, + "pro+" => 1 + 3, + _ => 15 + 3, + }; + } + private void GetAvailableSensors() { if (cumulus.WllApiKey == string.Empty || cumulus.WllApiSecret == string.Empty) diff --git a/CumulusMX/WeatherLinkDotCom.cs b/CumulusMX/WeatherLinkDotCom.cs index 8191eefa..d785a458 100644 --- a/CumulusMX/WeatherLinkDotCom.cs +++ b/CumulusMX/WeatherLinkDotCom.cs @@ -834,6 +834,7 @@ public class WlStationList public class WlStationListStations { public int station_id { get; set; } + public string station_id_uuid { get; set; } public string station_name { get; set; } public int gateway_id { get; set; } public string gateway_id_hex { get; set; } @@ -854,6 +855,9 @@ public class WlStationListStations public double latitude { get; set; } public double longitude { get; set; } public double elevation { get; set; } + public string gateway_type { get; set; } + public string relationship_type { get; set; } + public string subscription_type { get; set; } } public class WlSensor(int sensorType, int lsid, int parentId, string name, string parentName) diff --git a/CumulusMX/WeatherStation.cs b/CumulusMX/WeatherStation.cs index 5ef11788..6c187167 100644 --- a/CumulusMX/WeatherStation.cs +++ b/CumulusMX/WeatherStation.cs @@ -6129,7 +6129,7 @@ public void DoWind(double gustpar, int bearingpar, double speedpar, DateTime tim return; } - if (previousWind < 998 && (Math.Abs(speedpar - previousWind) > cumulus.Spike.WindDiff)) + if (speedpar >= 0 && previousWind < 998 && (Math.Abs(speedpar - previousWind) > cumulus.Spike.WindDiff)) { cumulus.LogSpikeRemoval("Wind difference greater than specified; reading ignored"); cumulus.LogSpikeRemoval($"Wind: NewVal={speedpar.ToString(cumulus.WindAvgFormat)} OldVal={previousWind.ToString(cumulus.WindAvgFormat)} SpikeWindDiff={cumulus.Spike.WindDiff.ToString(cumulus.WindAvgFormat)}"); @@ -6149,7 +6149,10 @@ public void DoWind(double gustpar, int bearingpar, double speedpar, DateTime tim } previousGust = gustpar; - previousWind = speedpar; + if (speedpar >= 0) + { + previousWind = speedpar; + } calibratedgust = cumulus.Calib.WindGust.Calibrate(gustpar); var uncalibratedspeed = speedpar < 0 ? WindAverageUncalibrated : speedpar; @@ -6237,10 +6240,31 @@ public void DoWind(double gustpar, int bearingpar, double speedpar, DateTime tim avg = totalwind / 15; } + if (avg >= 0 && previousWind < 998 && (Math.Abs(avg - previousWind) > cumulus.Spike.WindDiff)) + { + cumulus.LogSpikeRemoval("Wind difference greater than specified; reading ignored"); + cumulus.LogSpikeRemoval($"Wind: NewVal={speedpar.ToString(cumulus.WindAvgFormat)} OldVal={previousWind.ToString(cumulus.WindAvgFormat)} SpikeWindDiff={cumulus.Spike.WindDiff.ToString(cumulus.WindAvgFormat)}"); + lastSpikeRemoval = timestamp; + cumulus.SpikeAlarm.LastMessage = $"Wind difference greater than spike value - Wind: NewVal={avg.ToString(cumulus.WindAvgFormat)} OldVal={previousWind.ToString(cumulus.WindAvgFormat)} SpikeWindDiff={cumulus.Spike.WindDiff.ToString(cumulus.WindAvgFormat)}"; + cumulus.SpikeAlarm.Triggered = true; + return; + } + else if (avg >= cumulus.Limit.WindHigh) + { + cumulus.LogSpikeRemoval("Wind greater than upper limit; reading ignored"); + cumulus.LogSpikeRemoval($"Wind: NewVal={avg.ToString(cumulus.WindAvgFormat)} HighLimit={cumulus.Limit.WindHigh.ToString(cumulus.WindAvgFormat)}"); + lastSpikeRemoval = timestamp; + cumulus.SpikeAlarm.LastMessage = $"Wind greater than upper limit - Wind: NewVal={avg.ToString(cumulus.WindAvgFormat)} HighLimit={cumulus.Limit.WindHigh.ToString(cumulus.WindAvgFormat)}"; + cumulus.SpikeAlarm.Triggered = true; + return; + } + WindAverageUncalibrated = avg; // we want any calibration to be applied from uncalibrated values WindAverage = cumulus.Calib.WindSpeed.Calibrate(avg); + + previousWind = avg; } else { diff --git a/Updates.txt b/Updates.txt index 187754b6..3b8c9fd8 100644 --- a/Updates.txt +++ b/Updates.txt @@ -7,6 +7,8 @@ Changed Fixed - The Cumulus MX version comparison with latest online at startup and daily +- Davis Cloud Station can now accurately determine the current conditions update rate +- Fix Davis WLL (and others) creating erroneous wind speed spike warnings Package Updates From 4bab5a0f63d2cca011c6ea3842e00b72abcae5cc Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Thu, 1 Aug 2024 20:34:12 +0100 Subject: [PATCH 05/13] Add web tag #stationId which returns the internal station number --- CumulusMX/webtags.cs | 6 ++++++ Updates.txt | 2 ++ 2 files changed, 8 insertions(+) diff --git a/CumulusMX/webtags.cs b/CumulusMX/webtags.cs index 2beab54c..77ce32d3 100644 --- a/CumulusMX/webtags.cs +++ b/CumulusMX/webtags.cs @@ -3006,6 +3006,11 @@ private string TagstationtypeJsEnc(Dictionary tagParams) return cumulus.StationType == -1 ? "undefined" : EncodeForJs(cumulus.StationDesc[cumulus.StationType]); } + private string TagstationId(Dictionary tagParams) + { + return cumulus.StationType == -1 ? "undefined" : cumulus.StationType.ToString(); + } + private string Taglatitude(Dictionary tagParams) { var dpstr = tagParams.Get("dp"); @@ -6185,6 +6190,7 @@ public void InitialiseWebtags() { "graphperiod", Taggraphperiod }, { "stationtype", Tagstationtype }, { "stationtypeJsEnc", TagstationtypeJsEnc }, + { "stationId", TagstationId }, { "latitude", Taglatitude }, { "latitudeJsEnc", TaglatitudeJsEnc }, { "longitude", Taglongitude }, diff --git a/Updates.txt b/Updates.txt index 3b8c9fd8..af2661f4 100644 --- a/Updates.txt +++ b/Updates.txt @@ -2,6 +2,7 @@ 4.1.3 - b4028 ————————————— New +- New web tag <#stationId> which returns the internal station number used by CMX to determine the station type Changed @@ -9,6 +10,7 @@ Fixed - The Cumulus MX version comparison with latest online at startup and daily - Davis Cloud Station can now accurately determine the current conditions update rate - Fix Davis WLL (and others) creating erroneous wind speed spike warnings +- AI2 Davis reception stats Package Updates From f17e182c56de04886ec3eba1ef013c11157d838f Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Sun, 4 Aug 2024 17:32:00 +0100 Subject: [PATCH 06/13] Davis Cloud Station (VP2) now correctly displays the Davis ET values when "Cumulus calculates ET" is not enabled Davis WLL, and Davis Cloud stations, fixed a problem where the rollover would not be performed if historic data was not available and MX was stopped before the rollover and restarted after --- CumulusMX/Cumulus.cs | 2 ++ CumulusMX/DavisCloudStation.cs | 45 +++++++++++++++++++--------------- CumulusMX/DavisWllStation.cs | 29 ++++++++++++---------- Updates.txt | 9 ++++--- 4 files changed, 49 insertions(+), 36 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index 6b3e24c4..9e86e550 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -588,6 +588,8 @@ public void Initialise(int HTTPport, bool DebugEnabled, string startParms) boolWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + LogMessage("Dotnet Version: " + RuntimeInformation.FrameworkDescription); + // Some .NET 8 clutures use a non-"standard" minus symbol, this causes all sorts of parsing issues down the line and for external scripts // the simplest solution is to override this and set all cultures to use the hypen-minus if (CultureInfo.CurrentCulture.NumberFormat.NegativeSign != "-") diff --git a/CumulusMX/DavisCloudStation.cs b/CumulusMX/DavisCloudStation.cs index f5ca15b4..3c2d4934 100644 --- a/CumulusMX/DavisCloudStation.cs +++ b/CumulusMX/DavisCloudStation.cs @@ -24,6 +24,7 @@ internal partial class DavisCloudStation : WeatherStation private bool startingUp = true; private DateTime lastRecordTime = DateTime.MinValue; + private DateTime lastHistoricData; public DavisCloudStation(Cumulus cumulus) : base(cumulus) { @@ -362,6 +363,7 @@ public override void startReadingHistoryData() { cumulus.LogMessage("History: Reading history data from log files"); LoadLastHoursFromDataLogs(cumulus.LastUpdateTime); + lastHistoricData = cumulus.LastUpdateTime; cumulus.LogMessage("History: Reading archive data from WeatherLink API"); bw = new BackgroundWorker { WorkerSupportsCancellation = true }; @@ -417,7 +419,7 @@ private void GetHistoricData(BackgroundWorker worker) if (cumulus.WllApiKey == string.Empty || cumulus.WllApiSecret == string.Empty) { cumulus.LogWarningMessage("GetHistoricData: Missing WeatherLink API data in the configuration, aborting!"); - cumulus.LastUpdateTime = DateTime.Now; + lastHistoricData = DateTime.Now; return; } @@ -426,11 +428,10 @@ private void GetHistoricData(BackgroundWorker worker) const string msg = "No WeatherLink API station ID in the configuration"; cumulus.LogWarningMessage(msg); Cumulus.LogConsoleMessage("GetHistoricData: " + msg); - } var unixDateTime = Utils.ToUnixTime(DateTime.Now); - var startTime = Utils.ToUnixTime(cumulus.LastUpdateTime); + var startTime = Utils.ToUnixTime(lastHistoricData); long endTime = unixDateTime; int unix24hrs = 24 * 60 * 60; @@ -442,8 +443,8 @@ private void GetHistoricData(BackgroundWorker worker) maxArchiveRuns++; } - Cumulus.LogConsoleMessage($"Downloading Historic Data from WL.com from: {cumulus.LastUpdateTime:s} to: {Utils.FromUnixTime(endTime):s}"); - cumulus.LogMessage($"GetHistoricData: Downloading Historic Data from WL.com from: {cumulus.LastUpdateTime:s} to: {Utils.FromUnixTime(endTime):s}"); + Cumulus.LogConsoleMessage($"Downloading Historic Data from WL.com from: {lastHistoricData:s} to: {Utils.FromUnixTime(endTime):s}"); + cumulus.LogMessage($"GetHistoricData: Downloading Historic Data from WL.com from: {lastHistoricData:s} to: {Utils.FromUnixTime(endTime):s}"); StringBuilder historicUrl = new StringBuilder("https://api.weatherlink.com/v2/historic/" + cumulus.WllStationId); historicUrl.Append("?api-key=" + cumulus.WllApiKey); @@ -455,7 +456,7 @@ private void GetHistoricData(BackgroundWorker worker) lastDataReadTime = cumulus.LastUpdateTime; int luhour = lastDataReadTime.Hour; - int rollHour = Math.Abs(cumulus.GetHourInc(cumulus.LastUpdateTime)); + int rollHour = Math.Abs(cumulus.GetHourInc(lastHistoricData)); cumulus.LogMessage($"Roll over hour = {rollHour}"); @@ -489,7 +490,7 @@ private void GetHistoricData(BackgroundWorker worker) var historyError = responseBody.FromJson(); cumulus.LogErrorMessage($"GetHistoricData: WeatherLink API Historic Error: {historyError.code}, {historyError.message}"); Cumulus.LogConsoleMessage($" - Error {historyError.code}: {historyError.message}", ConsoleColor.Red); - cumulus.LastUpdateTime = Utils.FromUnixTime(endTime); + //cumulus.LastUpdateTime = Utils.FromUnixTime(endTime) return; } @@ -497,7 +498,7 @@ private void GetHistoricData(BackgroundWorker worker) { cumulus.LogWarningMessage("GetHistoricData: WeatherLink API Historic: No data was returned. Check your Device Id."); Cumulus.LogConsoleMessage(" - No historic data available"); - cumulus.LastUpdateTime = Utils.FromUnixTime(endTime); + lastHistoricData = Utils.FromUnixTime(endTime); return; } else if (responseBody.StartsWith("{\"")) // basic sanity check @@ -525,7 +526,7 @@ private void GetHistoricData(BackgroundWorker worker) { cumulus.LogMessage("GetHistoricData: No historic data available"); Cumulus.LogConsoleMessage(" - No historic data available"); - cumulus.LastUpdateTime = Utils.FromUnixTime(endTime); + lastHistoricData = Utils.FromUnixTime(endTime); return; } else @@ -537,7 +538,7 @@ private void GetHistoricData(BackgroundWorker worker) { cumulus.LogErrorMessage("GetHistoricData: Invalid historic message received"); cumulus.LogMessage("GetHistoricData: Received: " + responseBody); - cumulus.LastUpdateTime = Utils.FromUnixTime(endTime); + lastHistoricData = Utils.FromUnixTime(endTime); return; } } @@ -550,7 +551,7 @@ private void GetHistoricData(BackgroundWorker worker) cumulus.LogMessage($"GetHistoricData: Base exception - {ex.Message}"); } - cumulus.LastUpdateTime = Utils.FromUnixTime(endTime); + lastHistoricData = Utils.FromUnixTime(endTime); return; } @@ -745,6 +746,8 @@ private void GetHistoricData(BackgroundWorker worker) if (!Program.service) Console.WriteLine(""); // flush the progress line + + lastHistoricData = Utils.FromUnixTime(endTime); } @@ -1487,8 +1490,8 @@ private void DecodeCurrent(List sensors) * Available fields * solar_rad * et_day (inches) - ET field is populated in the ISS archive records, which may not be the same as the solar - * et_month - * et_year + * et_month - only incremented at rollover + * et_year - only incremented at rollover */ try { @@ -1497,9 +1500,9 @@ private void DecodeCurrent(List sensors) cumulus.LogDebugMessage("DecodeCurrent: using solar data"); DoSolarRad(data.solar_rad.Value, lastRecordTime); - if (data.et_year.HasValue && !cumulus.StationOptions.CalculatedET && (data.et_year.Value >= 0) && (data.et_year.Value < 32000)) + if (data.et_year.HasValue && data.et_day.HasValue && !cumulus.StationOptions.CalculatedET && (data.et_year.Value >= 0) && (data.et_year.Value < 32000)) { - DoET(ConvertUnits.RainINToUser(data.et_year.Value), lastRecordTime); + DoET(ConvertUnits.RainINToUser(data.et_year.Value + data.et_day.Value), lastRecordTime); } } } @@ -2015,9 +2018,9 @@ private void DecodeCurrent(List sensors) cumulus.LogWarningMessage($"DecodeCurrent: Warning, no valid Solar data on TxId {rec.tx_id}"); } - if (rec.et_year.HasValue && !cumulus.StationOptions.CalculatedET) + if (rec.et_year.HasValue && rec.et_day.HasValue && !cumulus.StationOptions.CalculatedET) { - DoET(ConvertUnits.RainINToUser(rec.et_year.Value), lastRecordTime); + DoET(ConvertUnits.RainINToUser(rec.et_year.Value + rec.et_day.Value), lastRecordTime); } } catch (Exception ex) @@ -3722,7 +3725,7 @@ private void GetAvailableStationIds(bool logToConsole = false) } catch (Exception ex) { - cumulus.LogDebugMessage("GetStations: WeatherLink API exception: " + ex.Message); + cumulus.LogErrorMessage("GetStations: WeatherLink API exception: " + ex.Message); } } @@ -3737,6 +3740,8 @@ private void SetDataTimeout(string subscription) "pro+" => 1 + 3, _ => 15 + 3, }; + + cumulus.LogMessage($"GetStations: Subscription type = {subscription}, update rate = {DataTimeoutMins} minutes"); } private void GetAvailableSensors() @@ -3785,7 +3790,7 @@ private void GetAvailableSensors() } catch (Exception ex) { - cumulus.LogDebugMessage("GetAvailableSensors: WeatherLink API exception: " + ex.Message); + cumulus.LogErrorMessage("GetAvailableSensors: WeatherLink API exception: " + ex.Message); return; } @@ -3821,7 +3826,7 @@ private void GetAvailableSensors() } catch (Exception ex) { - cumulus.LogDebugMessage("GetAvailableSensors: Processing sensors exception: " + ex.Message); + cumulus.LogErrorMessage("GetAvailableSensors: Processing sensors exception: " + ex.Message); } } } diff --git a/CumulusMX/DavisWllStation.cs b/CumulusMX/DavisWllStation.cs index 0589b150..6deeaba0 100644 --- a/CumulusMX/DavisWllStation.cs +++ b/CumulusMX/DavisWllStation.cs @@ -43,6 +43,7 @@ internal partial class DavisWllStation : WeatherStation private readonly List sensorList = []; private readonly bool useWeatherLinkDotCom = true; private readonly bool[] sensorContactLost = new bool[9]; + private DateTime lastHistoricData; public DavisWllStation(Cumulus cumulus) : base(cumulus) { @@ -1427,7 +1428,8 @@ private void SetTxBatteryStatus(int txId, int status) public override void startReadingHistoryData() { cumulus.LogMessage("WLL history: Reading history data from log files"); - LoadLastHoursFromDataLogs(cumulus.LastUpdateTime); + lastHistoricData = cumulus.LastUpdateTime; + LoadLastHoursFromDataLogs(lastHistoricData); cumulus.LogMessage("WLL history: Reading archive data from WeatherLink API"); bw = new BackgroundWorker { WorkerSupportsCancellation = true }; @@ -1496,7 +1498,7 @@ private void GetWlHistoricData(BackgroundWorker worker) if (cumulus.WllApiKey == string.Empty || cumulus.WllApiSecret == string.Empty) { cumulus.LogMessage("GetWlHistoricData: Missing WeatherLink API data in the configuration, aborting!"); - cumulus.LastUpdateTime = DateTime.Now; + lastHistoricData = DateTime.Now; return; } @@ -1505,11 +1507,10 @@ private void GetWlHistoricData(BackgroundWorker worker) const string msg = "No WeatherLink API station ID in the configuration"; cumulus.LogWarningMessage(msg); Cumulus.LogConsoleMessage("GetWlHistoricData: " + msg); - } var unixDateTime = Utils.ToUnixTime(DateTime.Now); - var startTime = Utils.ToUnixTime(cumulus.LastUpdateTime); + var startTime = Utils.ToUnixTime(lastHistoricData); long endTime = unixDateTime; int unix24hrs = 24 * 60 * 60; @@ -1521,8 +1522,8 @@ private void GetWlHistoricData(BackgroundWorker worker) maxArchiveRuns++; } - 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}"); + Cumulus.LogConsoleMessage($"Downloading Historic Data from WL.com from: {lastHistoricData:s} to: {Utils.FromUnixTime(endTime):s}"); + cumulus.LogMessage($"GetWlHistoricData: Downloading Historic Data from WL.com from: {lastHistoricData:s} to: {Utils.FromUnixTime(endTime):s}"); StringBuilder historicUrl = new StringBuilder("https://api.weatherlink.com/v2/historic/" + cumulus.WllStationId); historicUrl.Append("?api-key=" + cumulus.WllApiKey); @@ -1531,10 +1532,10 @@ private void GetWlHistoricData(BackgroundWorker worker) cumulus.LogDebugMessage($"WeatherLink URL = {historicUrl.ToString().Replace(cumulus.WllApiKey, "API_KEY")}"); - lastDataReadTime = cumulus.LastUpdateTime; + lastDataReadTime = lastHistoricData; int luhour = lastDataReadTime.Hour; - int rollHour = Math.Abs(cumulus.GetHourInc(cumulus.LastUpdateTime)); + int rollHour = Math.Abs(cumulus.GetHourInc(lastHistoricData)); cumulus.LogMessage($"Roll over hour = {rollHour}"); @@ -1568,7 +1569,7 @@ private void GetWlHistoricData(BackgroundWorker worker) var historyError = responseBody.FromJson(); cumulus.LogWarningMessage($"GetWlHistoricData: WeatherLink API Historic Error: {historyError.code}, {historyError.message}"); Cumulus.LogConsoleMessage($" - Error {historyError.code}: {historyError.message}", ConsoleColor.Red); - cumulus.LastUpdateTime = Utils.FromUnixTime(endTime); + lastHistoricData = Utils.FromUnixTime(endTime); return; } @@ -1576,7 +1577,7 @@ private void GetWlHistoricData(BackgroundWorker worker) { cumulus.LogWarningMessage("GetWlHistoricData: WeatherLink API Historic: No data was returned. Check your Device Id."); Cumulus.LogConsoleMessage(" - No historic data available"); - cumulus.LastUpdateTime = Utils.FromUnixTime(endTime); + lastHistoricData = Utils.FromUnixTime(endTime); return; } else if (responseBody.StartsWith("{\"")) // basic sanity check @@ -1604,7 +1605,7 @@ private void GetWlHistoricData(BackgroundWorker worker) { cumulus.LogMessage("GetWlHistoricData: No historic data available"); Cumulus.LogConsoleMessage(" - No historic data available"); - cumulus.LastUpdateTime = Utils.FromUnixTime(endTime); + lastHistoricData = Utils.FromUnixTime(endTime); return; } else @@ -1616,7 +1617,7 @@ private void GetWlHistoricData(BackgroundWorker worker) { cumulus.LogErrorMessage("GetWlHistoricData: Invalid historic message received"); cumulus.LogMessage("GetWlHistoricData: Received: " + responseBody); - cumulus.LastUpdateTime = Utils.FromUnixTime(endTime); + lastHistoricData = Utils.FromUnixTime(endTime); return; } } @@ -1629,7 +1630,7 @@ private void GetWlHistoricData(BackgroundWorker worker) cumulus.LogMessage($"GetWlHistoricData: Base exception - {ex.Message}"); } - cumulus.LastUpdateTime = Utils.FromUnixTime(endTime); + lastHistoricData = Utils.FromUnixTime(endTime); return; } @@ -1818,6 +1819,8 @@ private void GetWlHistoricData(BackgroundWorker worker) if (!Program.service) Console.WriteLine(""); // flush the progress line + + lastHistoricData = Utils.FromUnixTime(endTime); } private void DecodeHistoric(int dataType, int sensorType, string json) diff --git a/Updates.txt b/Updates.txt index af2661f4..216c076e 100644 --- a/Updates.txt +++ b/Updates.txt @@ -10,8 +10,11 @@ Fixed - The Cumulus MX version comparison with latest online at startup and daily - Davis Cloud Station can now accurately determine the current conditions update rate - Fix Davis WLL (and others) creating erroneous wind speed spike warnings -- AI2 Davis reception stats - +- AI2 Davis reception stats display incorrectly +- Davis Cloud Station (VP2) now correctly displays the Davis ET values when "Cumulus calculates ET" is not enabled + - Note: If "Cumulus calculates ET" is not enabled, the last hours ET every day, will be accumulated in the first hour of the following day +- + Davis WLL, and Davis Cloud stations, fixed a problem where the rollover would not be performed if historic data was not available and MX was stopped before the rollover and restarted after Package Updates - SixLabors.ImageSharp @@ -71,7 +74,7 @@ New - Cumulus now calculates the AQi for Ecowitt PM and CO₂ sensors - New web tags: <#AirQualityIdx1[-4]>, <#AirQualityAvgIdx1[-4]> - <#CO2_pm2p5_aqi>, <#CO2_pm2p5_24h_aqi>, <#CO2_pm10_aqi>, <#CO2_pm10_24_aqih> + <#CO2_pm2p5_aqi>, <#CO2_pm2p5_24h_aqi>, <#CO2_pm10_aqi>, <#CO2_pm10_24_aqi> - Add new pressure units option of kilopascal (kPa) - New station type added: JSON Data Input, marked as "experimental" for now, but testing so far has been successful - Accepts data in a JSON format defined in MXutils/WeatherStationInput.jsonc From 9a741e599db6b447295de35c3dec87a41aaa09df Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Sun, 11 Aug 2024 14:20:13 +0100 Subject: [PATCH 07/13] Add the ability to specifiy WeatherLink API station identifier as the UUID as well as Id. Applies to WLL and WL Cloud stations --- CumulusMX/Cumulus.cs | 3 +++ CumulusMX/DavisCloudStation.cs | 42 ++++++++++++++++++++++++---------- CumulusMX/DavisWllStation.cs | 24 +++++++++++++++---- CumulusMX/StationSettings.cs | 5 +++- 4 files changed, 56 insertions(+), 18 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index 9e86e550..51ec1e03 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -3912,6 +3912,7 @@ private void ReadIniFile() WllApiKey = ini.GetValue("WLL", "WLv2ApiKey", string.Empty); WllApiSecret = ini.GetValue("WLL", "WLv2ApiSecret", string.Empty); WllStationId = ini.GetValue("WLL", "WLStationId", -1, -1); + WllStationUuid = ini.GetValue("WLL", "WLStationUuid", ""); WllTriggerDataStoppedOnBroadcast = ini.GetValue("WLL", "DataStoppedOnBroadcast", true); WLLAutoUpdateIpAddress = ini.GetValue("WLL", "AutoUpdateIpAddress", true); WllBroadcastDuration = ini.GetValue("WLL", "BroadcastDuration", WllBroadcastDuration); @@ -5609,6 +5610,7 @@ internal void WriteIniFile() ini.SetValue("WLL", "WLv2ApiKey", Crypto.EncryptString(WllApiKey, Program.InstanceId, "WllApiKey")); ini.SetValue("WLL", "WLv2ApiSecret", Crypto.EncryptString(WllApiSecret, Program.InstanceId, "WllApiSecret")); ini.SetValue("WLL", "WLStationId", WllStationId); + ini.SetValue("WLL", "WLStationUuid", WllStationUuid); ini.SetValue("WLL", "DataStoppedOnBroadcast", WllTriggerDataStoppedOnBroadcast); ini.SetValue("WLL", "PrimaryRainTxId", WllPrimaryRain); ini.SetValue("WLL", "PrimaryTempHumTxId", WllPrimaryTempHum); @@ -7302,6 +7304,7 @@ public void WriteStringsFile() internal string WllApiKey; internal string WllApiSecret; internal int WllStationId; + internal string WllStationUuid; internal int WllParentId; internal bool WllTriggerDataStoppedOnBroadcast; // trigger a data stopped state if broadcasts stop being received but current data is OK /// Read-only setting, default 20 minutes (1200 sec) diff --git a/CumulusMX/DavisCloudStation.cs b/CumulusMX/DavisCloudStation.cs index 3c2d4934..c780c113 100644 --- a/CumulusMX/DavisCloudStation.cs +++ b/CumulusMX/DavisCloudStation.cs @@ -113,7 +113,7 @@ public DavisCloudStation(Cumulus cumulus) : base(cumulus) // If the Station ID is missing, this will populate it if the user only has one station associated with the API key if (cumulus.WllStationId < 10) { - var msg = "No WeatherLink API station ID in the cumulus.ini file"; + var msg = $"No WeatherLink API station ID {(cumulus.WllStationUuid == string.Empty ? "or UUID" : "")}in the cumulus.ini file" + (cumulus.WllStationUuid == string.Empty ? "" : ", but a UUID has been configured"); cumulus.LogWarningMessage(msg); Cumulus.LogConsoleMessage(msg); @@ -226,17 +226,18 @@ private async void GetCurrent(object source, ElapsedEventArgs e) return; } - if (cumulus.WllStationId < 10) + if (cumulus.WllStationId < 10 && cumulus.WllStationUuid == string.Empty) { - const string msg = "No WeatherLink API station ID in the configuration"; + const string msg = "No WeatherLink API station ID/UUID in the configuration"; cumulus.LogWarningMessage(msg); Cumulus.LogConsoleMessage("GetCurrent: " + msg); - + return; } cumulus.LogMessage($"GetWlCurrent: Downloading Current Data from weatherlink.com"); - StringBuilder currentUrl = new StringBuilder("https://api.weatherlink.com/v2/current/" + cumulus.WllStationId); + StringBuilder currentUrl = new StringBuilder("https://api.weatherlink.com/v2/current/"); + currentUrl.Append(cumulus.WllStationId > 10 ? cumulus.WllStationId.ToString() : cumulus.WllStationUuid); currentUrl.Append("?api-key=" + cumulus.WllApiKey); cumulus.LogDebugMessage($"WeatherLink URL = {currentUrl.ToString().Replace(cumulus.WllApiKey, "API_KEY")}"); @@ -423,11 +424,12 @@ private void GetHistoricData(BackgroundWorker worker) return; } - if (cumulus.WllStationId < 10) + if (cumulus.WllStationId < 10 && cumulus.WllStationUuid == string.Empty) { - const string msg = "No WeatherLink API station ID in the configuration"; + const string msg = "No WeatherLink API station ID/UUID in the configuration"; cumulus.LogWarningMessage(msg); Cumulus.LogConsoleMessage("GetHistoricData: " + msg); + return; } var unixDateTime = Utils.ToUnixTime(DateTime.Now); @@ -446,7 +448,8 @@ private void GetHistoricData(BackgroundWorker worker) Cumulus.LogConsoleMessage($"Downloading Historic Data from WL.com from: {lastHistoricData:s} to: {Utils.FromUnixTime(endTime):s}"); cumulus.LogMessage($"GetHistoricData: Downloading Historic Data from WL.com from: {lastHistoricData:s} to: {Utils.FromUnixTime(endTime):s}"); - StringBuilder historicUrl = new StringBuilder("https://api.weatherlink.com/v2/historic/" + cumulus.WllStationId); + StringBuilder historicUrl = new StringBuilder("https://api.weatherlink.com/v2/historic/"); + historicUrl.Append(cumulus.WllStationId > 10 ? cumulus.WllStationId.ToString() : cumulus.WllStationUuid); historicUrl.Append("?api-key=" + cumulus.WllApiKey); historicUrl.Append("&start-timestamp=" + startTime.ToString()); historicUrl.Append("&end-timestamp=" + endTime.ToString()); @@ -3690,7 +3693,7 @@ private void GetAvailableStationIds(bool logToConsole = false) { Cumulus.LogConsoleMessage($" - Found WeatherLink station id = {station.station_id}, name = {station.station_name}, active = {station.active}"); } - if (station.station_id == cumulus.WllStationId) + if (station.station_id == cumulus.WllStationId || station.station_id_uuid == cumulus.WllStationUuid) { cumulus.LogDebugMessage($"GetStations: Setting WLL parent ID = {station.gateway_id}"); cumulus.WllParentId = station.gateway_id; @@ -3702,17 +3705,32 @@ private void GetAvailableStationIds(bool logToConsole = false) wlStationArchiveInterval = station.recording_interval; SetDataTimeout(station.subscription_type); + + + if (cumulus.WllStationId < 10) + { + cumulus.WllStationId = station.station_id; + } + else if (cumulus.WllStationUuid == string.Empty) + { + cumulus.WllStationUuid = station.station_id_uuid; + } + + cumulus.WriteIniFile(); } } - if (stationsObj.stations.Count > 1 && cumulus.WllStationId < 10) + if (stationsObj.stations.Count > 1 && (cumulus.WllStationId < 10 && cumulus.WllStationUuid == string.Empty)) { if (logToConsole) Cumulus.LogConsoleMessage(" - Enter the required station id from the above list into your WLL configuration to enable history downloads."); } - else if (stationsObj.stations.Count == 1 && cumulus.WllStationId != stationsObj.stations[0].station_id) + else if (stationsObj.stations.Count == 1 && (cumulus.WllStationId != stationsObj.stations[0].station_id || cumulus.WllStationUuid != stationsObj.stations[0].station_id_uuid)) { - cumulus.LogMessage($"GetStations: Only found 1 WeatherLink station, using id = {stationsObj.stations[0].station_id}"); + var usedId = cumulus.WllStationId < 10 ? cumulus.WllStationId.ToString() : cumulus.WllStationUuid; + + cumulus.LogMessage($"GetStations: Only found 1 WeatherLink station, using id = {usedId}"); cumulus.WllStationId = stationsObj.stations[0].station_id; + cumulus.WllStationUuid = stationsObj.stations[0].station_id_uuid; // And save it to the config file cumulus.WriteIniFile(); diff --git a/CumulusMX/DavisWllStation.cs b/CumulusMX/DavisWllStation.cs index 6deeaba0..b618bc8a 100644 --- a/CumulusMX/DavisWllStation.cs +++ b/CumulusMX/DavisWllStation.cs @@ -134,10 +134,10 @@ public DavisWllStation(Cumulus cumulus) : base(cumulus) } // Perform Station ID checks - If we have API details! - // If the Station ID is missing, this will populate it if the user only has one station associated with the API key + // If the Station ID is missing, this will populate it if the user only has one station associated with the API key or the UUID is known if (useWeatherLinkDotCom && cumulus.WllStationId < 10) { - var msg = "No WeatherLink API station ID in the cumulus.ini file"; + var msg = $"No WeatherLink API station ID {(cumulus.WllStationUuid == string.Empty ? "or UUID" : "")}in the cumulus.ini file" + (cumulus.WllStationUuid == string.Empty ? "" : ", but a UUID has been configured"); cumulus.LogMessage(msg); Cumulus.LogConsoleMessage(msg); @@ -3044,7 +3044,7 @@ private void GetAvailableStationIds(bool logToConsole = false) { Cumulus.LogConsoleMessage($" - Found WeatherLink station id = {station.station_id}, name = {station.station_name}, active = {station.active}"); } - if (station.station_id == cumulus.WllStationId) + if (station.station_id == cumulus.WllStationId || cumulus.WllStationUuid == station.station_id_uuid) { cumulus.LogDebugMessage($"WLLStations: Setting WLL parent ID = {station.gateway_id}"); cumulus.WllParentId = station.gateway_id; @@ -3053,17 +3053,31 @@ private void GetAvailableStationIds(bool logToConsole = false) { cumulus.LogMessage($"WLLStations: - Cumulus log interval {Cumulus.logints[cumulus.DataLogInterval]} does not match this WeatherLink stations log interval {station.recording_interval}"); } + + if (cumulus.WllStationId < 10) + { + cumulus.WllStationId = station.station_id; + } + else if (cumulus.WllStationUuid == string.Empty) + { + cumulus.WllStationUuid = station.station_id_uuid; + } + + cumulus.WriteIniFile(); } } - if (stationsObj.stations.Count > 1 && cumulus.WllStationId < 10) + if (stationsObj.stations.Count > 1 && cumulus.WllStationId < 10 && cumulus.WllStationUuid == string.Empty) { if (logToConsole) Cumulus.LogConsoleMessage(" - Enter the required station id from the above list into your WLL configuration to enable history downloads."); } else if (stationsObj.stations.Count == 1 && cumulus.WllStationId != stationsObj.stations[0].station_id) { - cumulus.LogMessage($"WLLStations: Only found 1 WeatherLink station, using id = {stationsObj.stations[0].station_id}"); + var usedId = cumulus.WllStationId < 10 ? cumulus.WllStationId.ToString() : cumulus.WllStationUuid; + + cumulus.LogMessage($"WLLStations: Only found 1 WeatherLink station, using id = {usedId}"); cumulus.WllStationId = stationsObj.stations[0].station_id; + cumulus.WllStationUuid = stationsObj.stations[0].station_id_uuid; // And save it to the config file cumulus.WriteIniFile(); diff --git a/CumulusMX/StationSettings.cs b/CumulusMX/StationSettings.cs index ac888d89..0b9eadcd 100644 --- a/CumulusMX/StationSettings.cs +++ b/CumulusMX/StationSettings.cs @@ -329,7 +329,8 @@ internal string GetAlpacaFormData() { apiKey = cumulus.WllApiKey, apiSecret = cumulus.WllApiSecret, - apiStationId = cumulus.WllStationId + apiStationId = cumulus.WllStationId, + apiStationUuid = cumulus.WllStationUuid }; var wllPrimary = new JsonStationSettingsWllPrimary() @@ -795,6 +796,7 @@ internal string UpdateConfig(IHttpContext context) cumulus.WllApiKey = string.IsNullOrWhiteSpace(settings.daviswll.api.apiKey) ? null : settings.daviswll.api.apiKey.Trim(); cumulus.WllApiSecret = string.IsNullOrWhiteSpace(settings.daviswll.api.apiSecret) ? null : settings.daviswll.api.apiSecret.Trim(); cumulus.WllStationId = settings.daviswll.api.apiStationId; + cumulus.WllStationUuid = settings.daviswll.api.apiStationUuid; if (settings.general.stationtype == 11 || settings.general.stationtype == 19) // WLL & Cloud WLL/WLC only { @@ -1908,6 +1910,7 @@ internal class JsonStationSettingsWllApi public string apiKey { get; set; } public string apiSecret { get; set; } public int apiStationId { get; set; } + public string apiStationUuid { get; set; } } internal class JsonStationSettingsWllPrimary From 51cb5bf3f15ab6a1e14c5857304902286245d637 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Sun, 11 Aug 2024 14:28:39 +0100 Subject: [PATCH 08/13] Package update: FluentFTP & SQLite --- CumulusMX/Cumulus.cs | 1 - CumulusMX/CumulusMX.csproj | 4 ++-- Updates.txt | 6 ++++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index 51ec1e03..d8c3ed5b 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -12502,7 +12502,6 @@ public void RealtimeFTPLogin() Credentials = new NetworkCredential(FtpOptions.Username, FtpOptions.Password), }; - RealtimeFTP.Config.SocketPollInterval = 20000; // increase beyond the timeout value RealtimeFTP.Config.LogPassword = false; SetRealTimeFtpLogging(FtpOptions.Logging); diff --git a/CumulusMX/CumulusMX.csproj b/CumulusMX/CumulusMX.csproj index 17fdfa66..2fd0df41 100644 --- a/CumulusMX/CumulusMX.csproj +++ b/CumulusMX/CumulusMX.csproj @@ -71,11 +71,11 @@ - + - + diff --git a/Updates.txt b/Updates.txt index 216c076e..83baf9e5 100644 --- a/Updates.txt +++ b/Updates.txt @@ -3,6 +3,8 @@ ————————————— New - New web tag <#stationId> which returns the internal station number used by CMX to determine the station type +- For Davis WLL and WeatherLink Cloud stations you can now specify the station identifier using the stations UUID instead of the numeric Id. The UUID is simplier to find + as it forms part of the URL of every web page related to your station on weatherlink.com Changed @@ -13,8 +15,7 @@ Fixed - AI2 Davis reception stats display incorrectly - Davis Cloud Station (VP2) now correctly displays the Davis ET values when "Cumulus calculates ET" is not enabled - Note: If "Cumulus calculates ET" is not enabled, the last hours ET every day, will be accumulated in the first hour of the following day -- - Davis WLL, and Davis Cloud stations, fixed a problem where the rollover would not be performed if historic data was not available and MX was stopped before the rollover and restarted after +- Davis WLL, and Davis Cloud stations, fixed a problem where the rollover would not be performed if historic data was not available and MX was stopped before the rollover and restarted after Package Updates - SixLabors.ImageSharp @@ -23,6 +24,7 @@ Package Updates - NReco.Logging.File - ServiceStack.Text - SSH.Net +- SQLite From ed793014657f21abf8ef8ec7fc75808a0ea327f2 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Sun, 11 Aug 2024 16:25:41 +0100 Subject: [PATCH 09/13] Add cancellation token to Davis VP2 reconnects --- CumulusMX/DavisStation.cs | 53 ++++++++++++++++++++++++++++++++++----- Updates.txt | 1 + 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/CumulusMX/DavisStation.cs b/CumulusMX/DavisStation.cs index 85d74320..338f909c 100644 --- a/CumulusMX/DavisStation.cs +++ b/CumulusMX/DavisStation.cs @@ -649,6 +649,12 @@ private TcpClient OpenTcpPort() // Creating the new TCP socket effectively opens it - specify IP address or domain name and port while (attempt < 5 && !stop) { + if (cumulus.cancellationToken.IsCancellationRequested) + { + stop = true; + return null; + } + attempt++; cumulus.LogDebugMessage("OpenTcpPort: TCP Logger Connect attempt " + attempt); try @@ -677,7 +683,13 @@ private TcpClient OpenTcpPort() cumulus.LogErrorMessage("OpenTcpPort: Error - " + ex.Message); } - Thread.Sleep(1000); + cumulus.cancellationToken.WaitHandle.WaitOne(1000); + + if (cumulus.cancellationToken.IsCancellationRequested) + { + stop = true; + return null; + } } // Set the timeout of the underlying stream @@ -770,6 +782,11 @@ private void bw_DoWork(object sender, DoWorkEventArgs e) { do { + if (stop) + { + return; + } + GetArchiveData(); // The VP" seems to need a nudge after a DMPAFT command @@ -1182,7 +1199,13 @@ public override void Start() if (reconnecting) { cumulus.LogMessage("Failed to connect to the station, waiting 30 seconds before trying again"); - Thread.Sleep(30000); + cumulus.cancellationToken.WaitHandle.WaitOne(30000); + + if (cumulus.cancellationToken.IsCancellationRequested) + { + stop = true; + return; + } } continue; } @@ -3012,13 +3035,18 @@ private bool WakeVP(TcpClient thePort, bool force = false) int retryCount = 0; // Check if we haven't sent a command within the last two minutes - use 1:50 () to be safe - if (awakeStopWatch.IsRunning && awakeStopWatch.ElapsedMilliseconds < 110000 && !force) + if (awakeStopWatch.IsRunning && awakeStopWatch.ElapsedMilliseconds < 110000 && !force ) { cumulus.LogDebugMessage("WakeVP: Not required"); awakeStopWatch.Restart(); return true; } + if (stop) + { + return false; + } + cumulus.LogDebugMessage("WakeVP: Starting"); try @@ -3205,7 +3233,13 @@ private void InitSerial() if (comport == null || !comport.IsOpen) { cumulus.LogMessage("InitSerial: Failed to connect to the station, waiting 30 seconds before trying again"); - Thread.Sleep(30000); + cumulus.cancellationToken.WaitHandle.WaitOne(30000); + + if (cumulus.cancellationToken.IsCancellationRequested) + { + stop = true; + return; + } } } while (comport != null && !comport.IsOpen); @@ -3300,11 +3334,18 @@ private void InitTCP() socket = OpenTcpPort(); - if (socket == null && !stop) + if ((socket == null || !socket.Connected) && !stop) { cumulus.LogMessage("InitTCP: Failed to connect to the station, waiting 30 seconds before trying again"); Cumulus.LogConsoleMessage("Failed to connect to the station, waiting 30 seconds before trying again", ConsoleColor.Red, true); - Thread.Sleep(30000); + + cumulus.cancellationToken.WaitHandle.WaitOne(30000); + + if (cumulus.cancellationToken.IsCancellationRequested) + { + stop = true; + return; + } } } while ((socket == null || !socket.Connected) && !stop); diff --git a/Updates.txt b/Updates.txt index 83baf9e5..277d41e1 100644 --- a/Updates.txt +++ b/Updates.txt @@ -16,6 +16,7 @@ Fixed - Davis Cloud Station (VP2) now correctly displays the Davis ET values when "Cumulus calculates ET" is not enabled - Note: If "Cumulus calculates ET" is not enabled, the last hours ET every day, will be accumulated in the first hour of the following day - Davis WLL, and Davis Cloud stations, fixed a problem where the rollover would not be performed if historic data was not available and MX was stopped before the rollover and restarted after +- Improved Ctrl-C shutdown of Cumulus MX for Davis VP2 stations when they are failing to connect with the station Package Updates - SixLabors.ImageSharp From 8db83d965923a2ec45639b45ba3715eb6d1a2960 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Mon, 12 Aug 2024 18:06:38 +0100 Subject: [PATCH 10/13] Fix CMX version check when no betas are present on repo Fix Ecowitt firmware check when running test firmware --- CumulusMX/Cumulus.cs | 16 ++++++++++------ CumulusMX/EcowittApi.cs | 17 +++++++++++++---- Updates.txt | 3 +++ 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index d8c3ed5b..c9d89413 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -12914,7 +12914,11 @@ public async Task GetLatestVersion() var latestBeta = releases.Find(x => !x.draft && x.prerelease); var latestLive = releases.Find(x => !x.draft && !x.prerelease); var cmxBuild = int.Parse(Build); - var veryLatest = Math.Max(int.Parse(latestBeta.tag_name[1..]), int.Parse(latestLive.tag_name[1..])); + int veryLatest; + if (latestBeta == null) + veryLatest = int.Parse(latestLive.tag_name[1..]); + else + veryLatest = Math.Max(int.Parse(latestBeta.tag_name[1..]), int.Parse(latestLive.tag_name[1..])); if (string.IsNullOrEmpty(latestLive.name)) { @@ -12924,7 +12928,7 @@ public async Task GetLatestVersion() } return; } - else if (string.IsNullOrEmpty(latestBeta.name)) + else if (latestBeta != null && string.IsNullOrEmpty(latestBeta.name)) { LogMessage("Failed to get the latest beta build version from GitHub"); return; @@ -12941,13 +12945,13 @@ public async Task GetLatestVersion() UpgradeAlarm.Triggered = true; LatestBuild = latestLive.tag_name[1..]; } - else if (int.Parse(latestBeta.tag_name[1..]) == cmxBuild) + else if (latestBeta != null && int.Parse(latestBeta.tag_name[1..]) == cmxBuild) { LogMessage($"This Cumulus MX instance is running the latest beta version"); UpgradeAlarm.Triggered = false; LatestBuild = latestLive.tag_name[1..]; } - else if (int.Parse(latestBeta.tag_name[1..]) > cmxBuild) + else if (latestBeta != null && int.Parse(latestBeta.tag_name[1..]) > cmxBuild) { LogMessage($"This Cumulus MX beta instance is not running the latest beta version of Cumulsus MX, build {latestBeta.name} is available."); UpgradeAlarm.Triggered = false; @@ -12968,13 +12972,13 @@ public async Task GetLatestVersion() LogWarningMessage(msg); UpgradeAlarm.LastMessage = $"Release build {latestLive.name} is available"; UpgradeAlarm.Triggered = true; - LatestBuild = latestBeta.tag_name[1..]; + LatestBuild = latestBeta != null ? latestBeta.tag_name[1..] : latestLive.tag_name[1..]; } else if (int.Parse(latestLive.tag_name[1..]) == cmxBuild) { LogMessage($"This Cumulus MX instance is running the latest release version"); UpgradeAlarm.Triggered = false; - LatestBuild = latestBeta.tag_name[1..]; + LatestBuild = latestBeta != null ? latestBeta.tag_name[1..] : latestLive.tag_name[1..]; } else { diff --git a/CumulusMX/EcowittApi.cs b/CumulusMX/EcowittApi.cs index 073cfb91..95a9d69f 100644 --- a/CumulusMX/EcowittApi.cs +++ b/CumulusMX/EcowittApi.cs @@ -2612,10 +2612,19 @@ internal async Task GetLatestFirmwareVersion(string model, string mac, s } else if (retObj.code == 0) { - cumulus.FirmwareAlarm.LastMessage = $"A new firmware version is available: {retObj.data.name}.\nChange log:\n{retObj.data.content}"; - cumulus.FirmwareAlarm.Triggered = true; - cumulus.LogWarningMessage($"API.GetLatestFirmwareVersion: Latest Version {retObj.data.name}, Change log:\n{retObj.data.content}"); - return retObj.data.name; + if (retObj.data.content.Contains("test")) // "- This is a test firmware." + { + cumulus.LogMessage($"(\"API.GetLatestFirmwareVersion: You are running on test firmware: {retObj.data.name}"); + cumulus.FirmwareAlarm.Triggered = false; + return null; + } + else + { + cumulus.FirmwareAlarm.LastMessage = $"A new firmware version is available: {retObj.data.name}.\nChange log:\n{retObj.data.content}"; + cumulus.FirmwareAlarm.Triggered = true; + cumulus.LogWarningMessage($"API.GetLatestFirmwareVersion: Latest Version {retObj.data.name}, Change log:\n{retObj.data.content}"); + return retObj.data.name; + } } else { diff --git a/Updates.txt b/Updates.txt index 277d41e1..7c896e6c 100644 --- a/Updates.txt +++ b/Updates.txt @@ -17,6 +17,9 @@ Fixed - Note: If "Cumulus calculates ET" is not enabled, the last hours ET every day, will be accumulated in the first hour of the following day - Davis WLL, and Davis Cloud stations, fixed a problem where the rollover would not be performed if historic data was not available and MX was stopped before the rollover and restarted after - Improved Ctrl-C shutdown of Cumulus MX for Davis VP2 stations when they are failing to connect with the station +- Fix CMX version check when no betas are available on Github repo +- Fix Ecowitt firmware check when running test firmware + Package Updates - SixLabors.ImageSharp From 3d54f0d59e582dede11b8aacb1beaff950fc56f9 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Mon, 12 Aug 2024 18:10:44 +0100 Subject: [PATCH 11/13] Updates.txt --- Updates.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Updates.txt b/Updates.txt index 7c896e6c..114e3e5f 100644 --- a/Updates.txt +++ b/Updates.txt @@ -10,14 +10,14 @@ Changed Fixed - The Cumulus MX version comparison with latest online at startup and daily +- Fix CMX version check when no betas are available on Github repo - Davis Cloud Station can now accurately determine the current conditions update rate - Fix Davis WLL (and others) creating erroneous wind speed spike warnings -- AI2 Davis reception stats display incorrectly +- Alternative Interface 2 - Davis reception stats display incorrectly - Davis Cloud Station (VP2) now correctly displays the Davis ET values when "Cumulus calculates ET" is not enabled - Note: If "Cumulus calculates ET" is not enabled, the last hours ET every day, will be accumulated in the first hour of the following day - Davis WLL, and Davis Cloud stations, fixed a problem where the rollover would not be performed if historic data was not available and MX was stopped before the rollover and restarted after - Improved Ctrl-C shutdown of Cumulus MX for Davis VP2 stations when they are failing to connect with the station -- Fix CMX version check when no betas are available on Github repo - Fix Ecowitt firmware check when running test firmware From c893b99e32efc45373fe72425debfca030ae6a27 Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Thu, 15 Aug 2024 16:39:12 +0100 Subject: [PATCH 12/13] code tidy --- CumulusMX/GW1000Station.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CumulusMX/GW1000Station.cs b/CumulusMX/GW1000Station.cs index 4b51fd08..7d453761 100644 --- a/CumulusMX/GW1000Station.cs +++ b/CumulusMX/GW1000Station.cs @@ -775,7 +775,7 @@ private bool PrintSensorInfoNew(byte[] data, int idx) else { batt = $"{battV:f2}V ({TestBatteryWh40(data[battPos], battV)})"; // low = 1.2V - if (battV == 1.6) + if (battV >= 1.59) { batt += " dummy value?"; } From 0846c4659e0b8f976608950f8e8e9bdb0ab166ab Mon Sep 17 00:00:00 2001 From: Mark Crossley Date: Tue, 20 Aug 2024 17:15:24 +0100 Subject: [PATCH 13/13] Add Release/x86 configuration --- CumulusMX.sln | 7 ++++++- CumulusMX/CumulusMX.csproj | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CumulusMX.sln b/CumulusMX.sln index c60a4167..bbc1ae0a 100644 --- a/CumulusMX.sln +++ b/CumulusMX.sln @@ -1,4 +1,3 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.4.33205.214 @@ -13,13 +12,19 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {67A70E28-25C7-4C7F-BD7B-959AE6834B2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {67A70E28-25C7-4C7F-BD7B-959AE6834B2C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {67A70E28-25C7-4C7F-BD7B-959AE6834B2C}.Debug|x86.ActiveCfg = Debug|x86 + {67A70E28-25C7-4C7F-BD7B-959AE6834B2C}.Debug|x86.Build.0 = Debug|x86 {67A70E28-25C7-4C7F-BD7B-959AE6834B2C}.Release|Any CPU.ActiveCfg = Release|Any CPU {67A70E28-25C7-4C7F-BD7B-959AE6834B2C}.Release|Any CPU.Build.0 = Release|Any CPU + {67A70E28-25C7-4C7F-BD7B-959AE6834B2C}.Release|x86.ActiveCfg = Release|x86 + {67A70E28-25C7-4C7F-BD7B-959AE6834B2C}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/CumulusMX/CumulusMX.csproj b/CumulusMX/CumulusMX.csproj index 2fd0df41..d58ab862 100644 --- a/CumulusMX/CumulusMX.csproj +++ b/CumulusMX/CumulusMX.csproj @@ -15,6 +15,7 @@ False False annotations + AnyCPU;x86 @@ -25,6 +26,14 @@ 4 + + + TRACE;DEBUG;USE_SQLITEPCL_RAW + 1701;1702 + NU1605 + 4 + + none @@ -35,6 +44,16 @@ 4 + + + none + false + TRACE;USE_SQLITEPCL_RAW + 1701;1702 + NU1605 + 4 + + 4.1.3.4028 Copyright © 2015-$([System.DateTime]::Now.ToString('yyyy')) Cumulus MX