From 3609aae9c24bbfa362c2a5c6bd1d7ddd538e85a9 Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Thu, 4 Feb 2021 16:15:08 +0000 Subject: [PATCH 01/12] First pass at updating, rationalising, and enhancing the settings --- CumulusMX/AlarmSettings.cs | 8 +- CumulusMX/Cumulus.cs | 564 ++++++++++++------------ CumulusMX/DavisStation.cs | 142 +++++-- CumulusMX/DavisWllStation.cs | 20 +- CumulusMX/EasyWeather.cs | 8 +- CumulusMX/ExtraSensorSettings.cs | 77 ++-- CumulusMX/FOStation.cs | 34 +- CumulusMX/ImetStation.cs | 24 +- CumulusMX/InternetSettings.cs | 300 +++++++------ CumulusMX/MysqlSettings.cs | 149 ++++--- CumulusMX/NOAA.cs | 10 +- CumulusMX/NOAASettings.cs | 201 ++++----- CumulusMX/Program.cs | 5 + CumulusMX/ProgramSettings.cs | 43 +- CumulusMX/Properties/AssemblyInfo.cs | 6 +- CumulusMX/StationSettings.cs | 614 +++++++++++++++++++++------ CumulusMX/WMR200Station.cs | 2 +- CumulusMX/WS2300Station.cs | 6 +- CumulusMX/WeatherStation.cs | 318 +++++++------- CumulusMX/webtags.cs | 23 +- Updates.txt | 11 + 21 files changed, 1586 insertions(+), 979 deletions(-) diff --git a/CumulusMX/AlarmSettings.cs b/CumulusMX/AlarmSettings.cs index fe880535..75dfe181 100644 --- a/CumulusMX/AlarmSettings.cs +++ b/CumulusMX/AlarmSettings.cs @@ -21,10 +21,10 @@ public string GetAlarmSettings() var alarmUnits = new JsonAlarmUnits() { - tempUnits = cumulus.TempUnitText, - pressUnits = cumulus.PressUnitText, - rainUnits = cumulus.RainUnitText, - windUnits = cumulus.WindUnitText + tempUnits = cumulus.Units.TempText, + pressUnits = cumulus.Units.PressText, + rainUnits = cumulus.Units.RainText, + windUnits = cumulus.Units.WindText }; var data = new JsonAlarmSettingsData() diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index 63cdeac2..f617554d 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -116,8 +116,8 @@ public enum PrimaryAqSensor /* public struct Dataunits { - public pressunits pressunit; - public windunits windunit; + public Units.Presss Units.Press; + public Units.Winds Units.Wind; public tempunits tempunit; public rainunits rainunit; } @@ -217,27 +217,6 @@ public struct TExtraFiles private static readonly TraceListener FtpTraceListener = new TextWriterTraceListener("ftplog.txt", "ftplog"); - /// - /// Temperature unit currently in use - /// - public string TempUnitText; - - /// - /// Temperature trend unit in use, eg "°C/hr" - /// - public string TempTrendUnitText; - - public string RainUnitText; - - public string RainTrendUnitText; - - public string PressUnitText; - - public string PressTrendUnitText; - - public string WindUnitText; - - public string WindRunUnitText; public string AirQualityUnitText = "µg/m³"; public string SoilMoistureUnitText = "cb"; @@ -369,9 +348,7 @@ public struct TExtraFiles internal int[] FactorsOf60 = { 1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60 }; public TimeSpan AvgSpeedTime { get; set; } - public int AvgSpeedMinutes = 10; - public int PeakGustMinutes = 10; public TimeSpan PeakGustTime { get; set; } public TimeSpan AvgBearingTime { get; set; } @@ -391,14 +368,13 @@ public struct TExtraFiles internal int AirQualityDPlaces = 1; public string AirQualityFormat; - private int WindRunDPlaces = 1; + public int WindRunDPlaces = 1; public string WindRunFormat; public int RainDPlaces = 1; public string RainFormat; internal int PressDPlaces = 1; - internal bool davisIncrementPressureDP; public string PressFormat; internal int SunshineDPlaces = 1; @@ -409,12 +385,8 @@ public struct TExtraFiles public string ETFormat; - public int VPrainGaugeType = -1; - public string ComportName; public string DefaultComportName; - public int ImetBaudRate; - public int DavisBaudRate; public int vendorID; public int productID; @@ -450,9 +422,6 @@ public struct TExtraFiles internal int wsPort; private readonly bool DebuggingEnabled; - public bool UseDavisLoop2 = true; - public int DavisReadTimeout; - public SerialPort cmprtRG11; public SerialPort cmprt2RG11; @@ -467,8 +436,6 @@ public struct TExtraFiles private readonly string twitterKey = "lQiGNdtlYUJ4wS3d7souPw"; private readonly string twitterSecret = "AoB7OqimfoaSfGQAd47Hgatqdv3YeTTiqpinkje6Xg"; - public int FineOffsetReadTime; - public string AlltimeIniFile; public string Alltimelogfile; public string MonthlyAlltimeIniFile; @@ -529,6 +496,13 @@ public struct TExtraFiles public StationOptions StationOptions = new StationOptions(); + public StationUnits Units = new StationUnits(); + + public DavisOptions DavisOptions = new DavisOptions(); + public FineOffsetOptions FineOffsetOptions = new FineOffsetOptions(); + public ImetOptions ImetOptions = new ImetOptions(); + public EasyWeatherOptions EwOptions = new EasyWeatherOptions(); + public GraphOptions GraphOptions = new GraphOptions(); public SelectaChartOptions SelectaChartOptions = new SelectaChartOptions(); @@ -939,8 +913,16 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) // determine system uptime based on OS if (Platform.Substring(0, 3) == "Win") { - // Windows enable the performance counter method - UpTime = new PerformanceCounter("System", "System Up Time"); + try + { + // Windows enable the performance counter method + UpTime = new PerformanceCounter("System", "System Up Time"); + } + catch (Exception e) + { + LogMessage("Error: Unable to acces the System Up Time performance counter. System up time will not be available"); + LogDebugMessage($"Error: {e}"); + } } LogMessage("Current culture: " + CultureInfo.CurrentCulture.DisplayName); @@ -1089,7 +1071,7 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) { // Check uptime double ts = 0; - if (Platform.Substring(0, 3) == "Win") + if (Platform.Substring(0, 3) == "Win" && UpTime != null) { UpTime.NextValue(); ts = UpTime.NextValue(); @@ -1222,7 +1204,7 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) LogMessage("Spike logging is " + (ErrorLogSpikeRemoval ? "enabled" : "disabled")); LogMessage("Logging interval = " + logints[DataLogInterval] + " mins"); LogMessage("Real time interval = " + RealtimeInterval / 1000 + " secs"); - LogMessage("NoSensorCheck = " + (NoSensorCheck ? "1" : "0")); + LogMessage("NoSensorCheck = " + (StationOptions.NoSensorCheck ? "1" : "0")); TempFormat = "F" + TempDPlaces; WindFormat = "F" + WindDPlaces; @@ -1339,7 +1321,7 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) SetupUnitText(); - LogMessage($"WindUnit={WindUnitText} RainUnit={RainUnitText} TempUnit={TempUnitText} PressureUnit={PressUnitText}"); + LogMessage($"Units.Wind={Units.WindText} RainUnit={Units.RainText} TempUnit={Units.TempText} PressureUnit={Units.PressText}"); LogMessage($"YTDRain={YTDrain:F3} Year={YTDrainyear}"); LogMessage($"RainDayThreshold={RainDayThreshold:F3}"); LogMessage($"Roll over hour={RolloverHour}"); @@ -1597,7 +1579,7 @@ internal void SetStartOfRealtimeInsertSQL() { StartOfRealtimeInsertSQL = "INSERT IGNORE INTO " + MySqlRealtimeTable + " (" + "LogDateTime,temp,hum,dew,wspeed,wlatest,bearing,rrate,rfall,press," + - "currentwdir,beaufortnumber,windunit,tempunitnodeg,pressunit,rainunit," + + "currentwdir,beaufortnumber,Units.Wind,tempunitnodeg,Units.Press,rainunit," + "windrun,presstrendval,rmonth,ryear,rfallY,intemp,inhum,wchill,temptrend," + "tempTH,TtempTH,tempTL,TtempTL,windTM,TwindTM,wgustTM,TwgustTM," + "pressTH,TpressTH,pressTL,TpressTL,version,build,wgust,heatindex,humidex," + @@ -1620,9 +1602,9 @@ internal void SetRealtimeSqlCreateString() "press decimal(6," + PressDPlaces +") NOT NULL," + "currentwdir varchar(3) NOT NULL," + "beaufortnumber varchar(2) NOT NULL," + - "windunit varchar(4) NOT NULL," + + "Units.Wind varchar(4) NOT NULL," + "tempunitnodeg varchar(1) NOT NULL," + - "pressunit varchar(3) NOT NULL," + + "Units.Press varchar(3) NOT NULL," + "rainunit varchar(2) NOT NULL," + "windrun decimal(4," + WindRunDPlaces + ") NOT NULL," + "presstrendval varchar(6) NOT NULL," + @@ -1696,60 +1678,60 @@ internal void SetupUnitText() switch (TempUnit) { case 0: - TempUnitText = "°C"; - TempTrendUnitText = "°C/hr"; + Units.TempText = "°C"; + Units.TempTrendText = "°C/hr"; break; case 1: - TempUnitText = "°F"; - TempTrendUnitText = "°F/hr"; + Units.TempText = "°F"; + Units.TempTrendText = "°F/hr"; break; } switch (RainUnit) { case 0: - RainUnitText = "mm"; - RainTrendUnitText = "mm/hr"; + Units.RainText = "mm"; + Units.RainTrendText = "mm/hr"; break; case 1: - RainUnitText = "in"; - RainTrendUnitText = "in/hr"; + Units.RainText = "in"; + Units.RainTrendText = "in/hr"; break; } - switch (PressUnit) + switch (Units.Press) { case 0: - PressUnitText = "mb"; - PressTrendUnitText = "mb/hr"; + Units.PressText = "mb"; + Units.PressTrendText = "mb/hr"; break; case 1: - PressUnitText = "hPa"; - PressTrendUnitText = "hPa/hr"; + Units.PressText = "hPa"; + Units.PressTrendText = "hPa/hr"; break; case 2: - PressUnitText = "in"; - PressTrendUnitText = "in/hr"; + Units.PressText = "in"; + Units.PressTrendText = "in/hr"; break; } - switch (WindUnit) + switch (Units.Wind) { case 0: - WindUnitText = "m/s"; - WindRunUnitText = "km"; + Units.WindText = "m/s"; + Units.WindRunText = "km"; break; case 1: - WindUnitText = "mph"; - WindRunUnitText = "miles"; + Units.WindText = "mph"; + Units.WindRunText = "miles"; break; case 2: - WindUnitText = "km/h"; - WindRunUnitText = "km"; + Units.WindText = "km/h"; + Units.WindRunText = "km"; break; case 3: - WindUnitText = "kts"; - WindRunUnitText = "nm"; + Units.WindText = "kts"; + Units.WindRunText = "nm"; break; } } @@ -1991,10 +1973,10 @@ internal async void UpdateTwitter() else { // default message - status.Append($"Wind {station.WindAverage.ToString(WindAvgFormat)} {WindUnitText} {station.AvgBearingText}."); - status.Append($" Barometer {station.Pressure.ToString(PressFormat)} {PressUnitText}, {station.Presstrendstr}."); - status.Append($" Temperature {station.OutdoorTemperature.ToString(TempFormat)} {TempUnitText}."); - status.Append($" Rain today {station.RainToday.ToString(RainFormat)}{RainUnitText}."); + status.Append($"Wind {station.WindAverage.ToString(WindAvgFormat)} {Units.WindText} {station.AvgBearingText}."); + status.Append($" Barometer {station.Pressure.ToString(PressFormat)} {Units.PressText}, {station.Presstrendstr}."); + status.Append($" Temperature {station.OutdoorTemperature.ToString(TempFormat)} {Units.TempText}."); + status.Append($" Rain today {station.RainToday.ToString(RainFormat)}{Units.RainText}."); status.Append($" Humidity {station.OutdoorHumidity}%"); } @@ -3447,7 +3429,7 @@ public void RotateLogFiles() private void ReadIniFile() { var DavisBaudRates = new List { 1200, 2400, 4800, 9600, 14400, 19200 }; - var ImetBaudRates = new List { 19200, 115200 }; + ImetOptions.BaudRates = new List { 19200, 115200 }; LogMessage("Reading Cumulus.ini file"); //DateTimeToString(LongDate, "ddddd", Now); @@ -3482,44 +3464,46 @@ private void ReadIniFile() ProgramOptions.DataLogging = ini.GetValue("Station", "DataLogging", false); } - StationType = ini.GetValue("Station", "Type", -1); + ComportName = ini.GetValue("Station", "ComportName", DefaultComportName); + StationType = ini.GetValue("Station", "Type", -1); StationModel = ini.GetValue("Station", "Model", ""); FineOffsetStation = (StationType == StationTypes.FineOffset || StationType == StationTypes.FineOffsetSolar); DavisStation = (StationType == StationTypes.VantagePro || StationType == StationTypes.VantagePro2); - UseDavisLoop2 = ini.GetValue("Station", "UseDavisLoop2", true); - StationOptions.DavisReadReceptionStats = ini.GetValue("Station", "DavisReadReceptionStats", false); - DavisInitWaitTime = ini.GetValue("Station", "DavisInitWaitTime", 2000); - DavisIPResponseTime = ini.GetValue("Station", "DavisIPResponseTime", 500); - DavisReadTimeout = ini.GetValue("Station", "DavisReadTimeout", 1000); - davisIncrementPressureDP = ini.GetValue("Station", "DavisIncrementPressureDP", false); + // Davis Options + DavisOptions.UseLoop2 = ini.GetValue("Station", "UseDavisLoop2", true); + DavisOptions.ReadReceptionStats = ini.GetValue("Station", "DavisReadReceptionStats", false); + DavisOptions.SetLoggerInterval = ini.GetValue("Station", "DavisSetLoggerInterval", false); + DavisOptions.InitWaitTime = ini.GetValue("Station", "DavisInitWaitTime", 2000); + DavisOptions.IPResponseTime = ini.GetValue("Station", "DavisIPResponseTime", 500); + //StationOptions.DavisReadTimeout = ini.GetValue("Station", "DavisReadTimeout", 1000); // Not currently used + DavisOptions.IncrementPressureDP = ini.GetValue("Station", "DavisIncrementPressureDP", false); if (StationType == StationTypes.VantagePro) { - UseDavisLoop2 = false; + DavisOptions.UseLoop2 = false; } - - serial_port = ini.GetValue("Station", "Port", 0); - - ComportName = ini.GetValue("Station", "ComportName", DefaultComportName); - ImetBaudRate = ini.GetValue("Station", "ImetBaudRate", 19200); + DavisOptions.BaudRate = ini.GetValue("Station", "DavisBaudRate", 19200); // Check we have a valid value - if (!ImetBaudRates.Contains(ImetBaudRate)) + if (!DavisBaudRates.Contains(DavisOptions.BaudRate)) { // nope, that isn't allowed, set the default - LogMessage("Error, the value for ImetBaudRate in the ini file " + ImetBaudRate + " is not valid, using default 19200."); - ImetBaudRate = 19200; - } + LogMessage("Error, the value for DavisBaudRate in the ini file " + DavisOptions.BaudRate + " is not valid, using default 19200."); + DavisOptions.BaudRate = 19200; + } + DavisOptions.ForceVPBarUpdate = ini.GetValue("Station", "ForceVPBarUpdate", false); + //DavisUseDLLBarCalData = ini.GetValue("Station", "DavisUseDLLBarCalData", false); + //DavisCalcAltPress = ini.GetValue("Station", "DavisCalcAltPress", true); + //DavisConsoleHighGust = ini.GetValue("Station", "DavisConsoleHighGust", false); + DavisOptions.RainGaugeType = ini.GetValue("Station", "VPrainGaugeType", -1); + DavisOptions.ConnectionType = ini.GetValue("Station", "VP2ConnectionType", VP2SERIALCONNECTION); + DavisOptions.TCPPort = ini.GetValue("Station", "VP2TCPPort", 22222); + DavisOptions.IPAddr = ini.GetValue("Station", "VP2IPAddr", "0.0.0.0"); + //VPClosedownTime = ini.GetValue("Station", "VPClosedownTime", 99999999); + //VP2SleepInterval = ini.GetValue("Station", "VP2SleepInterval", 0); + DavisOptions.PeriodicDisconnectInterval = ini.GetValue("Station", "VP2PeriodicDisconnectInterval", 0); - DavisBaudRate = ini.GetValue("Station", "DavisBaudRate", 19200); - // Check we have a valid value - if (!DavisBaudRates.Contains(DavisBaudRate)) - { - // nope, that isn't allowed, set the default - LogMessage("Error, the value for DavisBaudRate in the ini file " + DavisBaudRate + " is not valid, using default 19200."); - DavisBaudRate = 19200; - } vendorID = ini.GetValue("Station", "VendorID", -1); productID = ini.GetValue("Station", "ProductID", -1); @@ -3551,44 +3535,44 @@ private void ReadIniFile() StationOptions.UseWind10MinAve = ini.GetValue("Station", "Wind10MinAverage", false); StationOptions.UseSpeedForAvgCalc = ini.GetValue("Station", "UseSpeedForAvgCalc", false); - AvgBearingMinutes = ini.GetValue("Station", "AvgBearingMinutes", 10); - if (AvgBearingMinutes > 120) + StationOptions.AvgBearingMinutes = ini.GetValue("Station", "AvgBearingMinutes", 10); + if (StationOptions.AvgBearingMinutes > 120) { - AvgBearingMinutes = 120; + StationOptions.AvgBearingMinutes = 120; } - if (AvgBearingMinutes == 0) + if (StationOptions.AvgBearingMinutes == 0) { - AvgBearingMinutes = 1; + StationOptions.AvgBearingMinutes = 1; } - AvgBearingTime = new TimeSpan(AvgBearingMinutes / 60, AvgBearingMinutes % 60, 0); + AvgBearingTime = new TimeSpan(StationOptions.AvgBearingMinutes / 60, StationOptions.AvgBearingMinutes % 60, 0); - AvgSpeedMinutes = ini.GetValue("Station", "AvgSpeedMinutes", 10); - if (AvgSpeedMinutes > 120) + StationOptions.AvgSpeedMinutes = ini.GetValue("Station", "AvgSpeedMinutes", 10); + if (StationOptions.AvgSpeedMinutes > 120) { - AvgSpeedMinutes = 120; + StationOptions.AvgSpeedMinutes = 120; } - if (AvgSpeedMinutes == 0) + if (StationOptions.AvgSpeedMinutes == 0) { - AvgSpeedMinutes = 1; + StationOptions.AvgSpeedMinutes = 1; } - AvgSpeedTime = new TimeSpan(AvgSpeedMinutes / 60, AvgSpeedMinutes % 60, 0); + AvgSpeedTime = new TimeSpan(StationOptions.AvgSpeedMinutes / 60, StationOptions.AvgSpeedMinutes % 60, 0); - LogMessage("ASM=" + AvgSpeedMinutes + " AST=" + AvgSpeedTime.ToString()); + LogMessage("AvgSpdMins=" + StationOptions.AvgSpeedMinutes + " AvgSpdTime=" + AvgSpeedTime.ToString()); - PeakGustMinutes = ini.GetValue("Station", "PeakGustMinutes", 10); - if (PeakGustMinutes > 120) + StationOptions.PeakGustMinutes = ini.GetValue("Station", "PeakGustMinutes", 10); + if (StationOptions.PeakGustMinutes > 120) { - PeakGustMinutes = 120; + StationOptions.PeakGustMinutes = 120; } - if (PeakGustMinutes == 0) + if (StationOptions.PeakGustMinutes == 0) { - PeakGustMinutes = 1; + StationOptions.PeakGustMinutes = 1; } - PeakGustTime = new TimeSpan(PeakGustMinutes / 60, PeakGustMinutes % 60, 0); + PeakGustTime = new TimeSpan(StationOptions.PeakGustMinutes / 60, StationOptions.PeakGustMinutes % 60, 0); if ((StationType == StationTypes.VantagePro) || (StationType == StationTypes.VantagePro2)) { @@ -3601,23 +3585,24 @@ private void ReadIniFile() UVdecimals = ini.GetValue("Station", "UVdecimals", UVdecimaldefault); - NoSensorCheck = ini.GetValue("Station", "NoSensorCheck", false); + StationOptions.NoSensorCheck = ini.GetValue("Station", "NoSensorCheck", false); StationOptions.CalculatedDP = ini.GetValue("Station", "CalculatedDP", false); StationOptions.CalculatedWC = ini.GetValue("Station", "CalculatedWC", false); RolloverHour = ini.GetValue("Station", "RolloverHour", 0); Use10amInSummer = ini.GetValue("Station", "Use10amInSummer", true); - ConfirmClose = ini.GetValue("Station", "ConfirmClose", false); - CloseOnSuspend = ini.GetValue("Station", "CloseOnSuspend", false); - RestartIfUnplugged = ini.GetValue("Station", "RestartIfUnplugged", false); - RestartIfDataStops = ini.GetValue("Station", "RestartIfDataStops", false); + //ConfirmClose = ini.GetValue("Station", "ConfirmClose", false); + //CloseOnSuspend = ini.GetValue("Station", "CloseOnSuspend", false); + //RestartIfUnplugged = ini.GetValue("Station", "RestartIfUnplugged", false); + //RestartIfDataStops = ini.GetValue("Station", "RestartIfDataStops", false); StationOptions.SyncTime = ini.GetValue("Station", "SyncDavisClock", false); - ClockSettingHour = ini.GetValue("Station", "ClockSettingHour", 4); + StationOptions.ClockSettingHour = ini.GetValue("Station", "ClockSettingHour", 4); StationOptions.WS2300IgnoreStationClock = ini.GetValue("Station", "WS2300IgnoreStationClock", false); + //WS2300Sync = ini.GetValue("Station", "WS2300Sync", false); StationOptions.LogExtraSensors = ini.GetValue("Station", "LogExtraSensors", false); ReportDataStoppedErrors = ini.GetValue("Station", "ReportDataStoppedErrors", true); ReportLostSensorContact = ini.GetValue("Station", "ReportLostSensorContact", true); - NoFlashWetDryDayRecords = ini.GetValue("Station", "NoFlashWetDryDayRecords", false); + //NoFlashWetDryDayRecords = ini.GetValue("Station", "NoFlashWetDryDayRecords", false); ErrorLogSpikeRemoval = ini.GetValue("Station", "ErrorLogSpikeRemoval", true); DataLogInterval = ini.GetValue("Station", "DataLogInterval", 2); // this is now an index @@ -3626,35 +3611,35 @@ private void ReadIniFile() DataLogInterval = 2; } - StationOptions.SyncFOReads = ini.GetValue("Station", "SyncFOReads", true); - FOReadAvoidPeriod = ini.GetValue("Station", "FOReadAvoidPeriod", 3); - FineOffsetReadTime = ini.GetValue("Station", "FineOffsetReadTime", 150); + FineOffsetOptions.FineOffsetSyncReads = ini.GetValue("Station", "SyncFOReads", true); + FineOffsetOptions.FineOffsetReadAvoidPeriod = ini.GetValue("Station", "FOReadAvoidPeriod", 3); + FineOffsetOptions.FineOffsetReadTime = ini.GetValue("Station", "FineOffsetReadTime", 150); - WS2300Sync = ini.GetValue("Station", "WS2300Sync", false); - WindUnit = ini.GetValue("Station", "WindUnit", 0); - PressUnit = ini.GetValue("Station", "PressureUnit", 0); + Units.Wind = ini.GetValue("Station", "Units.Wind", 0); + Units.Press = ini.GetValue("Station", "PressureUnit", 0); - RainUnit = ini.GetValue("Station", "RainUnit", 0); - TempUnit = ini.GetValue("Station", "TempUnit", 0); + Units.Rain = ini.GetValue("Station", "RainUnit", 0); + Units.Temp = ini.GetValue("Station", "TempUnit", 0); StationOptions.RoundWindSpeed = ini.GetValue("Station", "RoundWindSpeed", false); StationOptions.PrimaryAqSensor = ini.GetValue("Station", "PrimaryAqSensor", -1); // Unit decimals - RainDPlaces = RainDPlace[RainUnit]; - TempDPlaces = TempDPlace[TempUnit]; - PressDPlaces = PressDPlace[PressUnit]; - WindDPlaces = StationOptions.RoundWindSpeed ? 0 : WindDPlace[WindUnit]; + RainDPlaces = RainDPlaceDefaults[RainUnit]; + TempDPlaces = TempDPlaceDefaults[TempUnit]; + PressDPlaces = PressDPlaceDefaults[Units.Press]; + WindDPlaces = StationOptions.RoundWindSpeed ? 0 : WindDPlaceDefaults[Units.Wind]; WindAvgDPlaces = WindDPlaces; + AirQualityDPlaces = 1; - // Unit decimal overrides - readonly + // Unit decimal overrides WindDPlaces = ini.GetValue("Station", "WindSpeedDecimals", WindDPlaces); WindAvgDPlaces = ini.GetValue("Station", "WindSpeedAvgDecimals", WindAvgDPlaces); WindRunDPlaces = ini.GetValue("Station", "WindRunDecimals", WindRunDPlaces); SunshineDPlaces = ini.GetValue("Station", "SunshineHrsDecimals", 1); - if ((StationType == 0 || StationType == 1) && davisIncrementPressureDP) + if ((StationType == 0 || StationType == 1) && DavisOptions.IncrementPressureDP) { // Use one more DP for Davis stations ++PressDPlaces; @@ -3672,11 +3657,15 @@ private void ReadIniFile() YTDrain = ini.GetValue("Station", "YTDrain", 0.0); YTDrainyear = ini.GetValue("Station", "YTDrainyear", 0); - EWInterval = ini.GetValue("Station", "EWInterval", 1.0); - EWFile = ini.GetValue("Station", "EWFile", ""); - EWallowFF = ini.GetValue("Station", "EWFF", false); - EWdisablecheckinit = ini.GetValue("Station", "EWdisablecheckinit", false); - EWduplicatecheck = ini.GetValue("Station", "EWduplicatecheck", true); + EwOptions.Interval = ini.GetValue("Station", "EWInterval", 1.0); + EwOptions.Filename = ini.GetValue("Station", "EWFile", ""); + //EWallowFF = ini.GetValue("Station", "EWFF", false); + //EWdisablecheckinit = ini.GetValue("Station", "EWdisablecheckinit", false); + //EWduplicatecheck = ini.GetValue("Station", "EWduplicatecheck", true); + EwOptions.MinPressMB = ini.GetValue("Station", "EWminpressureMB", 900); + EwOptions.MaxPressMB = ini.GetValue("Station", "EWmaxpressureMB", 1200); + EwOptions.MaxRainTipDiff = ini.GetValue("Station", "EWMaxRainTipDiff", 30); + EwOptions.PressOffset = ini.GetValue("Station", "EWpressureoffset", 9999.0); Spike.TempDiff = ini.GetValue("Station", "EWtempdiff", 999.0); Spike.PressDiff = ini.GetValue("Station", "EWpressurediff", 999.0); @@ -3686,28 +3675,23 @@ private void ReadIniFile() Spike.MaxRainRate = ini.GetValue("Station", "EWmaxRainRate", 999.0); Spike.MaxHourlyRain = ini.GetValue("Station", "EWmaxHourlyRain", 999.0); - EWminpressureMB = ini.GetValue("Station", "EWminpressureMB", 900); - EWmaxpressureMB = ini.GetValue("Station", "EWmaxpressureMB", 1200); - - EWMaxRainTipDiff = ini.GetValue("Station", "EWMaxRainTipDiff", 30); - - EWpressureoffset = ini.GetValue("Station", "EWpressureoffset", 9999.0); - LCMaxWind = ini.GetValue("Station", "LCMaxWind", 9999); - StationOptions.ForceVPBarUpdate = ini.GetValue("Station", "ForceVPBarUpdate", false); - DavisUseDLLBarCalData = ini.GetValue("Station", "DavisUseDLLBarCalData", false); - DavisCalcAltPress = ini.GetValue("Station", "DavisCalcAltPress", true); - DavisConsoleHighGust = ini.GetValue("Station", "DavisConsoleHighGust", false); - VPrainGaugeType = ini.GetValue("Station", "VPrainGaugeType", -1); - RecordsBeganDate = ini.GetValue("Station", "StartDate", DateTime.Now.ToLongDateString()); LogMessage("Cumulus start date: " + RecordsBeganDate); - ImetWaitTime = ini.GetValue("Station", "ImetWaitTime", 500); // readonly setting - delay to wait for a reply to a command - ImetReadDelay = ini.GetValue("Station", "ImetReadDelay", 500); // readonly setting - delay between sending read live data commands - ImetUpdateLogPointer = ini.GetValue("Station", "ImetUpdateLogPointer", true); // readonly setting - keep the logger pointer pointing at last data read + ImetOptions.ImetWaitTime = ini.GetValue("Station", "ImetWaitTime", 500); // delay to wait for a reply to a command + ImetOptions.ImetReadDelay = ini.GetValue("Station", "ImetReadDelay", 500); // delay between sending read live data commands + ImetOptions.ImetUpdateLogPointer = ini.GetValue("Station", "ImetUpdateLogPointer", true); // keep the logger pointer pointing at last data read + ImetOptions.ImetBaudRate = ini.GetValue("Station", "ImetOptions.ImetBaudRate", 19200); + // Check we have a valid value + if (!ImetOptions.BaudRates.Contains(ImetOptions.ImetBaudRate)) + { + // nope, that isn't allowed, set the default + LogMessage("Error, the value for ImetOptions.ImetBaudRate in the ini file " + ImetOptions.ImetBaudRate + " is not valid, using default 19200."); + ImetOptions.ImetBaudRate = 19200; + } UseDataLogger = ini.GetValue("Station", "UseDataLogger", true); UseCumulusForecast = ini.GetValue("Station", "UseCumulusForecast", false); @@ -3728,6 +3712,8 @@ private void ReadIniFile() FCPressureThreshold = ini.GetValue("Station", "FCPressureThreshold", -1.0); RainSeasonStart = ini.GetValue("Station", "RainSeasonStart", 1); + if (RainSeasonStart < 1 || RainSeasonStart > 12) + RainSeasonStart = 1; ChillHourSeasonStart = ini.GetValue("Station", "ChillHourSeasonStart", 10); ChillHourThreshold = ini.GetValue("Station", "ChillHourThreshold", -999.0); @@ -3752,29 +3738,20 @@ private void ReadIniFile() if (FCPressureThreshold < 0) { - FCPressureThreshold = PressUnit == 2 ? 0.00295333727 : 0.1; + FCPressureThreshold = Units.Press == 2 ? 0.00295333727 : 0.1; } special_logging = ini.GetValue("Station", "SpecialLog", false); solar_logging = ini.GetValue("Station", "SolarLog", false); - VP2ConnectionType = ini.GetValue("Station", "VP2ConnectionType", VP2SERIALCONNECTION); - VP2TCPPort = ini.GetValue("Station", "VP2TCPPort", 22222); - VP2IPAddr = ini.GetValue("Station", "VP2IPAddr", "0.0.0.0"); - - VPClosedownTime = ini.GetValue("Station", "VPClosedownTime", 99999999); - - VP2SleepInterval = ini.GetValue("Station", "VP2SleepInterval", 0); - - VP2PeriodicDisconnectInterval = ini.GetValue("Station", "VP2PeriodicDisconnectInterval", 0); - RTdisconnectcount = ini.GetValue("Station", "RTdisconnectcount", 0); + //RTdisconnectcount = ini.GetValue("Station", "RTdisconnectcount", 0); WMR928TempChannel = ini.GetValue("Station", "WMR928TempChannel", 0); WMR200TempChannel = ini.GetValue("Station", "WMR200TempChannel", 1); - CreateWxnowTxt = ini.GetValue("Station", "CreateWxnowTxt", true); + CreateWxnowTxt = ini.GetValue("Station", "CreateWxnowTxt", false); ListWebTags = ini.GetValue("Station", "ListWebTags", false); @@ -4429,32 +4406,61 @@ internal void WriteIniFile() ini.SetValue("Station", "Humidity98Fix", StationOptions.Humidity98Fix); ini.SetValue("Station", "Wind10MinAverage", StationOptions.UseWind10MinAve); ini.SetValue("Station", "UseSpeedForAvgCalc", StationOptions.UseSpeedForAvgCalc); - ini.SetValue("Station", "DavisReadReceptionStats", StationOptions.DavisReadReceptionStats); + ini.SetValue("Station", "AvgBearingMinutes", StationOptions.AvgBearingMinutes); + ini.SetValue("Station", "AvgSpeedMinutes", StationOptions.AvgSpeedMinutes); + ini.SetValue("Station", "PeakGustMinutes", StationOptions.PeakGustMinutes); + + ini.SetValue("Station", "DavisReadReceptionStats", DavisOptions.ReadReceptionStats); + ini.SetValue("Station", "DavisSetLoggerInterval", DavisOptions.SetLoggerInterval); + ini.SetValue("Station", "UseDavisLoop2", DavisOptions.UseLoop2); + ini.SetValue("Station", "DavisInitWaitTime", DavisOptions.InitWaitTime); + ini.SetValue("Station", "DavisIPResponseTime", DavisOptions.IPResponseTime); + ini.SetValue("Station", "DavisBaudRate", DavisOptions.BaudRate); + ini.SetValue("Station", "VPrainGaugeType", DavisOptions.RainGaugeType); + ini.SetValue("Station", "VP2ConnectionType", DavisOptions.ConnectionType); + ini.SetValue("Station", "VP2TCPPort", DavisOptions.TCPPort); + ini.SetValue("Station", "VP2IPAddr", DavisOptions.IPAddr); + ini.SetValue("Station", "VP2PeriodicDisconnectInterval", DavisOptions.PeriodicDisconnectInterval); + + ini.SetValue("Station", "NoSensorCheck", StationOptions.NoSensorCheck); ini.SetValue("Station", "CalculatedDP", StationOptions.CalculatedDP); ini.SetValue("Station", "CalculatedWC", StationOptions.CalculatedWC); ini.SetValue("Station", "RolloverHour", RolloverHour); ini.SetValue("Station", "Use10amInSummer", Use10amInSummer); - ini.SetValue("Station", "ConfirmClose", ConfirmClose); - ini.SetValue("Station", "CloseOnSuspend", CloseOnSuspend); - ini.SetValue("Station", "RestartIfUnplugged", RestartIfUnplugged); - ini.SetValue("Station", "RestartIfDataStops", RestartIfDataStops); + //ini.SetValue("Station", "ConfirmClose", ConfirmClose); + //ini.SetValue("Station", "CloseOnSuspend", CloseOnSuspend); + //ini.SetValue("Station", "RestartIfUnplugged", RestartIfUnplugged); + //ini.SetValue("Station", "RestartIfDataStops", RestartIfDataStops); ini.SetValue("Station", "SyncDavisClock", StationOptions.SyncTime); - ini.SetValue("Station", "ClockSettingHour", ClockSettingHour); - ini.SetValue("Station", "SyncFOReads", StationOptions.SyncFOReads); + ini.SetValue("Station", "ClockSettingHour", StationOptions.ClockSettingHour); + ini.SetValue("Station", "SyncFOReads", FineOffsetOptions.FineOffsetSyncReads); + ini.SetValue("Station", "FOReadAvoidPeriod", FineOffsetOptions.FineOffsetReadAvoidPeriod); + ini.SetValue("Station", "FineOffsetReadTime", FineOffsetOptions.FineOffsetReadTime); ini.SetValue("Station", "WS2300IgnoreStationClock", StationOptions.WS2300IgnoreStationClock); ini.SetValue("Station", "LogExtraSensors", StationOptions.LogExtraSensors); ini.SetValue("Station", "DataLogInterval", DataLogInterval); - ini.SetValue("Station", "WindUnit", WindUnit); - ini.SetValue("Station", "PressureUnit", PressUnit); - ini.SetValue("Station", "RainUnit", RainUnit); - ini.SetValue("Station", "TempUnit", TempUnit); + + ini.SetValue("Station", "WindUnit", Units.Wind); + ini.SetValue("Station", "PressureUnit", Units.Press); + ini.SetValue("Station", "RainUnit", Units.Rain); + ini.SetValue("Station", "TempUnit", Units.Temp); + + ini.SetValue("Station", "WindSpeedDecimals", WindDPlaces); + ini.SetValue("Station", "WindSpeedAvgDecimals", WindAvgDPlaces); + ini.SetValue("Station", "WindRunDecimals", WindRunDPlaces); + ini.SetValue("Station", "SunshineHrsDecimals", SunshineDPlaces); + ini.SetValue("Station", "PressDecimals", PressDPlaces); + ini.SetValue("Station", "RainDecimals", RainDPlaces); + ini.SetValue("Station", "TempDecimals", TempDPlaces); + ini.SetValue("Station", "UVDecimals", UVDPlaces); + ini.SetValue("Station", "AirQualityDecimals", AirQualityDPlaces); + + ini.SetValue("Station", "LocName", LocationName); ini.SetValue("Station", "LocDesc", LocationDesc); ini.SetValue("Station", "StartDate", RecordsBeganDate); ini.SetValue("Station", "YTDrain", YTDrain); ini.SetValue("Station", "YTDrainyear", YTDrainyear); - ini.SetValue("Station", "EWInterval", EWInterval); - ini.SetValue("Station", "EWFile", EWFile); ini.SetValue("Station", "UseDataLogger", UseDataLogger); ini.SetValue("Station", "UseCumulusForecast", UseCumulusForecast); ini.SetValue("Station", "HourlyForecast", HourlyForecast); @@ -4462,14 +4468,18 @@ internal void WriteIniFile() ini.SetValue("Station", "FCpressinMB", FCpressinMB); ini.SetValue("Station", "FClowpress", FClowpress); ini.SetValue("Station", "FChighpress", FChighpress); - ini.SetValue("Station", "ForceVPBarUpdate", StationOptions.ForceVPBarUpdate); + ini.SetValue("Station", "ForceVPBarUpdate", DavisOptions.ForceVPBarUpdate); ini.SetValue("Station", "UseZeroBearing", StationOptions.UseZeroBearing); - ini.SetValue("Station", "VP2ConnectionType", VP2ConnectionType); - ini.SetValue("Station", "VP2TCPPort", VP2TCPPort); - ini.SetValue("Station", "VP2IPAddr", VP2IPAddr); ini.SetValue("Station", "RoundWindSpeed", StationOptions.RoundWindSpeed); ini.SetValue("Station", "PrimaryAqSensor", StationOptions.PrimaryAqSensor); - ini.SetValue("Station", "VP2PeriodicDisconnectInterval", VP2PeriodicDisconnectInterval); + + ini.SetValue("Station", "EWInterval", EwOptions.Interval); + ini.SetValue("Station", "EWFile", EwOptions.Filename); + ini.SetValue("Station", "EWminpressureMB", EwOptions.MinPressMB); + ini.SetValue("Station", "EWmaxpressureMB", EwOptions.MaxPressMB); + ini.SetValue("Station", "EWMaxRainTipDiff", EwOptions.MaxRainTipDiff); + ini.SetValue("Station", "EWpressureoffset", EwOptions.PressOffset); + ini.SetValue("Station", "EWtempdiff", Spike.TempDiff); ini.SetValue("Station", "EWpressurediff", Spike.PressDiff); ini.SetValue("Station", "EWhumiditydiff", Spike.HumidityDiff); @@ -4478,16 +4488,15 @@ internal void WriteIniFile() ini.SetValue("Station", "EWmaxHourlyRain", Spike.MaxHourlyRain); ini.SetValue("Station", "EWmaxRainRate", Spike.MaxRainRate); - ini.SetValue("Station", "EWminpressureMB", EWminpressureMB); - ini.SetValue("Station", "EWmaxpressureMB", EWmaxpressureMB); - ini.SetValue("Station", "RainSeasonStart", RainSeasonStart); ini.SetValue("Station", "RainDayThreshold", RainDayThreshold); ini.SetValue("Station", "ErrorLogSpikeRemoval", ErrorLogSpikeRemoval); - //ini.SetValue("Station", "ImetBaudRate", ImetBaudRate); - //ini.SetValue("Station", "DavisBaudRate", DavisBaudRate); + ini.SetValue("Station", "ImetOptions.ImetBaudRate", ImetOptions.ImetBaudRate); + ini.SetValue("Station", "ImetWaitTime", ImetOptions.ImetWaitTime); // delay to wait for a reply to a command + ini.SetValue("Station", "ImetReadDelay", ImetOptions.ImetReadDelay); // delay between sending read live data commands + ini.SetValue("Station", "ImetUpdateLogPointer", ImetOptions.ImetUpdateLogPointer); // keep the logger pointer pointing at last data read ini.SetValue("Station", "RG11Enabled", RG11Enabled); ini.SetValue("Station", "RG11portName", RG11Port); @@ -5391,22 +5400,15 @@ private void ReadStringsFile() public int RTdisconnectcount { get; set; } - public int VP2PeriodicDisconnectInterval { get; set; } - - public int VP2SleepInterval { get; set; } + //public int VP2SleepInterval { get; set; } - public int VPClosedownTime { get; set; } - public string VP2IPAddr { get; set; } + //public int VPClosedownTime { get; set; } public string AirLinkInIPAddr { get; set; } public string AirLinkOutIPAddr { get; set; } public bool AirLinkInEnabled { get; set; } public bool AirLinkOutEnabled { get; set; } - public int VP2TCPPort { get; set; } - - public int VP2ConnectionType { get; set; } - public bool solar_logging { get; set; } public bool special_logging { get; set; } @@ -5460,12 +5462,6 @@ private void ReadStringsFile() public bool UseDataLogger { get; set; } - public int ImetWaitTime { get; set; } - - public int ImetReadDelay { get; set; } - - public bool ImetUpdateLogPointer { get; set; } - public bool DavisConsoleHighGust { get; set; } public bool DavisCalcAltPress { get; set; } @@ -5474,25 +5470,13 @@ private void ReadStringsFile() public int LCMaxWind { get; set; } - public double EWpressureoffset { get; set; } - - public int EWMaxRainTipDiff { get; set; } - - public int EWmaxpressureMB { get; set; } - - public int EWminpressureMB { get; set; } - - public bool EWduplicatecheck { get; set; } + //public bool EWduplicatecheck { get; set; } public string RecordsBeganDate { get; set; } - public bool EWdisablecheckinit { get; set; } - - public bool EWallowFF { get; set; } - - public string EWFile { get; set; } + //public bool EWdisablecheckinit { get; set; } - public double EWInterval { get; set; } + //public bool EWallowFF { get; set; } public int YTDrainyear { get; set; } @@ -5510,47 +5494,36 @@ private void ReadStringsFile() public string HTTPProxyName { get; set; } - public int[] WindDPlace = { 1, 1, 1, 1 }; - public int[] TempDPlace = { 1, 1 }; - public int[] PressDPlace = { 1, 1, 2 }; - public int[] RainDPlace = { 1, 2 }; + public int[] WindDPlaceDefaults = { 1, 1, 1, 1 }; + public int[] TempDPlaceDefaults = { 1, 1 }; + public int[] PressDPlaceDefaults = { 1, 1, 2 }; + public int[] RainDPlaceDefaults = { 1, 2 }; public const int numextrafiles = 99; public const int numOfSelectaChartSeries = 6; public int RainUnit { get; set; } - public int PressUnit { get; set; } - public int WindUnit { get; set; } - - public bool WS2300Sync { get; set; } - - public int FOReadAvoidPeriod { get; set; } + //public bool WS2300Sync { get; set; } public bool ErrorLogSpikeRemoval { get; set; } - public bool NoFlashWetDryDayRecords { get; set; } + //public bool NoFlashWetDryDayRecords { get; set; } public bool ReportLostSensorContact { get; set; } public bool ReportDataStoppedErrors { get; set; } - public int ClockSettingHour { get; set; } - - public bool RestartIfDataStops { get; set; } + //public bool RestartIfDataStops { get; set; } - public bool RestartIfUnplugged { get; set; } + //public bool RestartIfUnplugged { get; set; } - public bool CloseOnSuspend { get; set; } + //public bool CloseOnSuspend { get; set; } - public bool ConfirmClose { get; set; } + //public bool ConfirmClose { get; set; } public int DataLogInterval { get; set; } - public bool NoSensorCheck { get; set; } - - public int serial_port { get; set; } - public int UVdecimals { get; set; } public int UVdecimaldefault { get; set; } @@ -5559,8 +5532,6 @@ private void ReadStringsFile() public string LatTxt { get; set; } - public int AvgBearingMinutes { get; set; } - public int TempUnit { get; set; } public bool AltitudeInFeet { get; set; } @@ -5583,8 +5554,6 @@ private void ReadStringsFile() public DateTime Dawn; public DateTime Dusk; public TimeSpan DaylightLength { get; set; } - public int DavisInitWaitTime { get; set; } - public int DavisIPResponseTime { get; set; } public int GraphHours { get; set; } // WeatherLink Live transmitter Ids and indexes @@ -7831,10 +7800,10 @@ 59 8.4 Feels Like temperature file.Write(station.Pressure.ToString(PressFormat, InvC) + ' '); // 11 file.Write(station.CompassPoint(station.Bearing) + ' '); // 12 file.Write(Beaufort(station.WindAverage) + ' '); // 13 - file.Write(WindUnitText + ' '); // 14 - file.Write(TempUnitText[1].ToString() + ' '); // 15 - file.Write(PressUnitText + ' '); // 16 - file.Write(RainUnitText + ' '); // 17 + file.Write(Units.WindText + ' '); // 14 + file.Write(Units.TempText[1].ToString() + ' '); // 15 + file.Write(Units.PressText + ' '); // 16 + file.Write(Units.RainText + ' '); // 17 file.Write(station.WindRunToday.ToString(WindRunFormat, InvC) + ' '); // 18 if (station.presstrendval > 0) file.Write('+' + station.presstrendval.ToString(PressFormat, InvC) + ' '); // 19 @@ -7909,10 +7878,10 @@ 59 8.4 Feels Like temperature values.Append(station.Pressure.ToString(PressFormat, InvC) + ",'"); values.Append(station.CompassPoint(station.Bearing) + "','"); values.Append(Beaufort(station.WindAverage) + "','"); - values.Append(WindUnitText + "','"); - values.Append(TempUnitText[1].ToString() + "','"); - values.Append(PressUnitText + "','"); - values.Append(RainUnitText + "',"); + values.Append(Units.WindText + "','"); + values.Append(Units.TempText[1].ToString() + "','"); + values.Append(Units.PressText + "','"); + values.Append(Units.RainText + "',"); values.Append(station.WindRunToday.ToString(WindRunFormat, InvC) + ",'"); values.Append((station.presstrendval > 0 ? '+' + station.presstrendval.ToString(PressFormat, InvC) : station.presstrendval.ToString(PressFormat, InvC)) + "',"); values.Append(station.RainMonth.ToString(RainFormat, InvC) + ','); @@ -9231,6 +9200,33 @@ public class ProgramOptionsClass public bool WarnMultiple { get; set; } } + public class StationUnits + { + public int Wind { get; set; } + public int Press { get; set; } + public int Rain { get; set; } + public int Temp { get; set; } + + public string WindText { get; set; } + public string PressText { get; set; } + public string RainText { get; set; } + public string TempText { get; set; } + + public string TempTrendText { get; set; } + public string RainTrendText { get; set; } + public string PressTrendText { get; set; } + public string WindRunText { get; set; } + public string AirQualityUnitText { get; set; } + public string SoilMoistureUnitText { get; set; } + public string CO2UnitText { get; set; } + + public StationUnits() + { + AirQualityUnitText = "µg/m³"; + SoilMoistureUnitText = "cb"; + CO2UnitText = "ppm"; + } + } public class StationOptions { @@ -9241,15 +9237,61 @@ public class StationOptions public bool CalculatedDP { get; set; } public bool CalculatedWC { get; set; } public bool SyncTime { get; set; } + public int ClockSettingHour { get; set; } public bool UseCumulusPresstrendstr { get; set; } - public bool ForceVPBarUpdate { get; set; } public bool LogExtraSensors { get; set; } public bool WS2300IgnoreStationClock { get; set; } public bool RoundWindSpeed { get; set; } - public bool SyncFOReads { get; set; } - public bool DavisReadReceptionStats { get; set; } public int PrimaryAqSensor { get; set; } -} + public bool NoSensorCheck { get; set; } + public int AvgBearingMinutes { get; set; } + public int AvgSpeedMinutes { get; set; } + public int PeakGustMinutes { get; set; } + } + + public class DavisOptions + { + public bool ForceVPBarUpdate { get; set; } + public bool ReadReceptionStats { get; set; } + public bool SetLoggerInterval { get; set; } + public bool UseLoop2 { get; set; } + public int InitWaitTime { get; set; } + public int IPResponseTime { get; set; } + public int ReadTimeout { get; set; } + public bool IncrementPressureDP { get; set; } + public int BaudRate { get; set; } + public int RainGaugeType { get; set; } + public int ConnectionType { get; set; } + public int TCPPort { get; set; } + public string IPAddr { get; set; } + public int PeriodicDisconnectInterval { get; set; } + } + + public class FineOffsetOptions + { + public bool FineOffsetSyncReads { get; set; } + public int FineOffsetReadAvoidPeriod { get; set; } + public int FineOffsetReadTime { get; set; } + } + + public class ImetOptions + { + public List BaudRates { get; set; } + public int ImetBaudRate { get; set; } + public int ImetWaitTime { get; set; } + public int ImetReadDelay { get; set; } + public bool ImetUpdateLogPointer { get; set; } + } + + public class EasyWeatherOptions + { + public double Interval { get; set; } + public string Filename { get; set; } + public int MinPressMB { get; set; } + public int MaxPressMB { get; set; } + public int MaxRainTipDiff { get; set; } + public double PressOffset { get; set; } + } public class GraphOptions { diff --git a/CumulusMX/DavisStation.cs b/CumulusMX/DavisStation.cs index 97c7f26a..f551c578 100644 --- a/CumulusMX/DavisStation.cs +++ b/CumulusMX/DavisStation.cs @@ -44,17 +44,17 @@ public DavisStation(Cumulus cumulus) : base(cumulus) calculaterainrate = false; - isSerial = (cumulus.VP2ConnectionType == 0); + isSerial = (cumulus.DavisOptions.ConnectionType == 0); bool connectedOK; cumulus.LogMessage("Station type = Davis"); - cumulus.LogMessage("LOOP2 " + (cumulus.UseDavisLoop2 ? "enabled" : "disabled")); + cumulus.LogMessage("LOOP2 " + (cumulus.DavisOptions.UseLoop2 ? "enabled" : "disabled")); if (isSerial) { cumulus.LogMessage("Serial device = " + cumulus.ComportName); - cumulus.LogMessage("Serial speed = " + cumulus.DavisBaudRate); + cumulus.LogMessage("Serial speed = " + cumulus.DavisOptions.BaudRate); InitSerial(); @@ -62,11 +62,11 @@ public DavisStation(Cumulus cumulus) : base(cumulus) } else { - ipaddr = cumulus.VP2IPAddr; - port = Convert.ToInt32(cumulus.VP2TCPPort); + ipaddr = cumulus.DavisOptions.IPAddr; + port = Convert.ToInt32(cumulus.DavisOptions.TCPPort); cumulus.LogMessage("IP address = " + ipaddr + " Port = " + port); - cumulus.LogMessage("periodic disconnect = " + cumulus.VP2PeriodicDisconnectInterval); + cumulus.LogMessage("periodic disconnect = " + cumulus.DavisOptions.PeriodicDisconnectInterval); InitTCP(); @@ -99,11 +99,11 @@ public DavisStation(Cumulus cumulus) : base(cumulus) cumulus.LogMessage("FW version = " + DavisFirmwareVersion); try { - if (DavisFirmwareVersion == "???" && cumulus.UseDavisLoop2) + if (DavisFirmwareVersion == "???" && cumulus.DavisOptions.UseLoop2) { cumulus.LogMessage("Unable to determine the firmare version, LOOP2 may not be supported"); } - else if((float.Parse(DavisFirmwareVersion, CultureInfo.InvariantCulture.NumberFormat) < (float)1.9) && cumulus.UseDavisLoop2) + else if((float.Parse(DavisFirmwareVersion, CultureInfo.InvariantCulture.NumberFormat) < (float)1.9) && cumulus.DavisOptions.UseLoop2) { cumulus.LogMessage("LOOP2 is enabled in Cumulus.ini but this firmware version does not support it. Consider disabling it in Cumulus.ini"); cumulus.LogConsoleMessage("Your console firmware version does not support LOOP2. Consider disabling it in Cumulus.ini"); @@ -114,7 +114,7 @@ public DavisStation(Cumulus cumulus) : base(cumulus) cumulus.LogDebugMessage("Error parsing firmware string for version number: " + ex.Message); } - if (cumulus.StationOptions.DavisReadReceptionStats) + if (cumulus.DavisOptions.ReadReceptionStats) { var recepStats = GetReceptionStats(); DecodeReceptionStats(recepStats); @@ -419,9 +419,90 @@ private void CheckLoggerInterval() var msg = $"** WARNING: Your station logger interval {readBuffer[0]} mins does not match your Cumulus MX logging interval {cumulus.logints[cumulus.DataLogInterval]} mins"; cumulus.LogConsoleMessage(msg); cumulus.LogMessage("CheckLoggerInterval: " + msg); + + if (cumulus.DavisOptions.SetLoggerInterval) + { + SetLoggerInterval(cumulus.logints[cumulus.DataLogInterval]); + } + } + } + + private void SetLoggerInterval(int interval) + { + cumulus.LogMessage($"SetLoggerInterval: Seting logger interval to {interval} minutes"); + + // response should be just an ACK + if (isSerial) + { + string commandString = $"SETPER {interval}"; + if (WakeVP(comport)) + { + try + { + comport.WriteLine(commandString); + + if (!WaitForACK(comport)) + { + cumulus.LogMessage("SetLoggerInterval: No ACK in response to setting logger interval"); + return; + } + + cumulus.LogMessage("SetLoggerInterval: Logger interval changed OK"); + } + catch (TimeoutException) + { + cumulus.LogMessage("SetLoggerInterval: Timed out waiting for a response"); + } + catch (Exception ex) + { + cumulus.LogMessage("SetLoggerInterval: Error - " + ex.Message); + awakeStopWatch.Stop(); + } + } + } + else + { + string commandString = $"SETPER {interval}\n"; + if (WakeVP(socket)) + { + try + { + NetworkStream stream = socket.GetStream(); + stream.ReadTimeout = TcpWaitTimeMs; + stream.WriteTimeout = TcpWaitTimeMs; + + stream.Write(Encoding.ASCII.GetBytes(commandString), 0, commandString.Length); + + if (!WaitForACK(stream)) + { + cumulus.LogMessage("SetLoggerInterval: No ACK in response to setting logger interval"); + return; + } + + cumulus.LogMessage("SetLoggerInterval: Logger interval changed OK"); + } + catch (System.IO.IOException ex) + { + if (ex.Message.Contains("did not properly respond after a period")) + { + cumulus.LogMessage("SetLoggerInterval: Timed out waiting for a response"); + } + else + { + cumulus.LogMessage("SetLoggerInterval: Error - " + ex.Message); + awakeStopWatch.Stop(); + } + } + catch (Exception ex) + { + cumulus.LogMessage("SetLoggerInterval: Error - " + ex.Message); + awakeStopWatch.Stop(); + } + } } } + private string GetReceptionStats() { // e.g. OK 21629 15 0 3204 128 @@ -652,6 +733,7 @@ public override void Stop() catch { } + } private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) @@ -814,7 +896,7 @@ public override void portDataReceived(object sender, SerialDataReceivedEventArgs public override void Start() { cumulus.LogMessage("Start normal reading loop"); - int loopcount = cumulus.StationOptions.ForceVPBarUpdate ? 20 : 50; + int loopcount = cumulus.DavisOptions.ForceVPBarUpdate ? 20 : 50; const int loop2count = 1; bool reconnecting = false; @@ -867,7 +949,7 @@ public override void Start() { if (comport != null && comport.IsOpen) { - if (cumulus.UseDavisLoop2 && SendLoopCommand(comport, "LPS 2 " + loop2count)) + if (cumulus.DavisOptions.UseLoop2 && SendLoopCommand(comport, "LPS 2 " + loop2count)) { GetAndProcessLoop2Data(loop2count); } @@ -909,7 +991,7 @@ public override void Start() if (socket != null && socket.Connected) { - if (cumulus.UseDavisLoop2 && SendLoopCommand(socket, "LPS 2 " + loop2count + Newline)) + if (cumulus.DavisOptions.UseLoop2 && SendLoopCommand(socket, "LPS 2 " + loop2count + Newline)) { GetAndProcessLoop2Data(loop2count); } @@ -933,12 +1015,12 @@ public override void Start() } } - if (cumulus.StationOptions.ForceVPBarUpdate && !stop) + if (cumulus.DavisOptions.ForceVPBarUpdate && !stop) { SendBarRead(); } - if (!cumulus.StationOptions.DavisReadReceptionStats || lastRecepStatsTime.AddMinutes(15) >= DateTime.Now || stop) + if (!cumulus.DavisOptions.ReadReceptionStats || lastRecepStatsTime.AddMinutes(15) >= DateTime.Now || stop) continue; var recepStats = GetReceptionStats(); @@ -1158,7 +1240,7 @@ private bool SendLoopCommand(TcpClient tcpPort, string commandString) // flush the input stream stream.WriteByte(10); - Thread.Sleep(cumulus.DavisIPResponseTime); + Thread.Sleep(cumulus.DavisOptions.IPResponseTime); while (stream.DataAvailable) { @@ -1222,7 +1304,7 @@ private void GetAndProcessLoopData(int number) if (min != previousMinuteSetClock) { previousMinuteSetClock = min; - if (cumulus.StationOptions.SyncTime && DateTime.Now.Hour == cumulus.ClockSettingHour && min == 0) + if (cumulus.StationOptions.SyncTime && DateTime.Now.Hour == cumulus.StationOptions.ClockSettingHour && min == 0) { // set the console clock clockSetNeeded = true; @@ -1273,7 +1355,7 @@ private void GetAndProcessLoopData(int number) else { // See if we need to disconnect to allow Weatherlink IP to upload - if (cumulus.VP2PeriodicDisconnectInterval > 0) + if (cumulus.DavisOptions.PeriodicDisconnectInterval > 0) { min = DateTime.Now.Minute; @@ -1299,7 +1381,7 @@ private void GetAndProcessLoopData(int number) } // Wait - Thread.Sleep(cumulus.VP2PeriodicDisconnectInterval*1000); + Thread.Sleep(cumulus.DavisOptions.PeriodicDisconnectInterval *1000); cumulus.LogDebugMessage("LOOP: Attempting reconnect to logger"); InitTCP(); @@ -1907,7 +1989,7 @@ private void GetAndProcessLoop2Data(int number) } // Check if the station 10 minute gust value is greater than ours - only if our gust period is 10 minutes or more though - if (loopData.WindGust10Min < 200 && cumulus.PeakGustMinutes >= 10) + if (loopData.WindGust10Min < 200 && cumulus.StationOptions.PeakGustMinutes >= 10) { // Extract 10-min gust and see if it is higher than we have recorded. var gust10min = ConvertWindMPHToUser(loopData.WindGust10Min)*cumulus.Calib.WindGust.Mult; @@ -2204,7 +2286,7 @@ private void GetArchiveData() while (socket.Available < pageSize && responsePasses < 20) { // Wait a short period to let more data load into the buffer - Thread.Sleep(cumulus.DavisIPResponseTime); + Thread.Sleep(cumulus.DavisOptions.IPResponseTime); responsePasses++; } @@ -2360,7 +2442,7 @@ private void GetArchiveData() DoHumidex(timestamp); // add in 'archivePeriod' minutes worth of wind speed to windrun - WindRunToday += ((WindAverage * WindRunHourMult[cumulus.WindUnit] * interval) / 60.0); + WindRunToday += ((WindAverage * WindRunHourMult[cumulus.Units.Wind] * interval) / 60.0); DateTime windruncheckTS; if ((h == rollHour) && (timestamp.Minute == 0)) @@ -2873,7 +2955,7 @@ private bool WakeVP(TcpClient thePort) cumulus.LogDebugMessage($"WakeVP: Sending newline ({passCount}/{maxPasses})"); stream.WriteByte(LF); - Thread.Sleep(cumulus.DavisIPResponseTime); + Thread.Sleep(cumulus.DavisOptions.IPResponseTime); int thisChar; do @@ -2974,7 +3056,7 @@ private void InitSerial() try { - comport = new SerialPort(cumulus.ComportName, cumulus.DavisBaudRate, Parity.None, 8, StopBits.One) + comport = new SerialPort(cumulus.ComportName, cumulus.DavisOptions.BaudRate, Parity.None, 8, StopBits.One) { Handshake = Handshake.None, DtrEnable = true, @@ -3078,12 +3160,12 @@ private void InitTCP() socket = OpenTcpPort(); - if (socket == null) + if (socket == null && !stop) { cumulus.LogMessage("InitTCP: Failed to connect to the station, waiting 30 seconds before trying again"); Thread.Sleep(30000); } - } while (socket == null || !socket.Connected); + } while ((socket == null || !socket.Connected) && !stop); try { @@ -3095,7 +3177,7 @@ private void InitTCP() // stop loop data stream.WriteByte(0x0A); - Thread.Sleep(cumulus.DavisInitWaitTime); + Thread.Sleep(cumulus.DavisOptions.InitWaitTime); byte[] buffer1 = new byte[1000]; byte[] buffer2 = new byte[buffer1.Length]; @@ -3116,7 +3198,7 @@ private void InitTCP() cumulus.LogDebugMessage($"InitTCP: Sending TEST ({tryCount}) command"); stream.Write(Encoding.ASCII.GetBytes("TEST\n"), 0, 5); - Thread.Sleep(cumulus.DavisInitWaitTime); + Thread.Sleep(cumulus.DavisOptions.InitWaitTime); while (stream.DataAvailable) { @@ -3196,7 +3278,7 @@ private bool WaitForOK(NetworkStream stream) var readBuffer = new StringBuilder(); cumulus.LogDebugMessage("WaitForOK: Wait for OK"); - Thread.Sleep(cumulus.DavisIPResponseTime); + Thread.Sleep(cumulus.DavisOptions.IPResponseTime); do { @@ -3298,7 +3380,7 @@ private bool WaitForACK(NetworkStream stream, int timeoutMs = -1) // in the buffer first or no response is given. If all else fails, try again. cumulus.LogDebugMessage("WaitForACK: Starting"); - Thread.Sleep(cumulus.DavisIPResponseTime); + Thread.Sleep(cumulus.DavisOptions.IPResponseTime); if (timeoutMs > -1) { @@ -3639,7 +3721,7 @@ internal double ConvertRainClicksToInternal(double clicks) private double ConvertRainClicksToUser(double clicks) { // One click is either 0.01 inches or 0.2 mm - switch (cumulus.VPrainGaugeType) + switch (cumulus.DavisOptions.RainGaugeType) { case 0: // Rain gauge is metric, convert to user unit diff --git a/CumulusMX/DavisWllStation.cs b/CumulusMX/DavisWllStation.cs index 0ca4a5be..059e014b 100644 --- a/CumulusMX/DavisWllStation.cs +++ b/CumulusMX/DavisWllStation.cs @@ -67,12 +67,12 @@ public DavisWllStation(Cumulus cumulus) : base(cumulus) dogsBodyClient.DefaultRequestHeaders.Add("Connection", "close"); // If the user is using the default 10 minute Wind gust, always use gust data from the WLL - simple - if (cumulus.PeakGustMinutes == 10) + if (cumulus.StationOptions.PeakGustMinutes == 10) { CalcRecentMaxGust = false; checkWllGustValues = false; } - else if (cumulus.PeakGustMinutes > 10) + else if (cumulus.StationOptions.PeakGustMinutes > 10) { // If the user period is greater that 10 minutes, then Cumulus must calculate Gust values // but we can check the WLL 10 min gust value in case we missed a gust @@ -328,7 +328,7 @@ private async void GetWllRealtime(object source, ElapsedEventArgs e) lock (threadSafer) { - ip = cumulus.VP2IPAddr; + ip = cumulus.DavisOptions.IPAddr; } if (CheckIpValid(ip)) @@ -388,7 +388,7 @@ private async void GetWllCurrent(object source, ElapsedEventArgs e) lock (threadSafer) { - ip = cumulus.VP2IPAddr; + ip = cumulus.DavisOptions.IPAddr; } if (CheckIpValid(ip)) @@ -419,6 +419,7 @@ private async void GetWllCurrent(object source, ElapsedEventArgs e) DoDayResetIfNeeded(); startupDayResetIfRequired = false; } + retry = 9; } catch (Exception ex) { @@ -430,7 +431,6 @@ private async void GetWllCurrent(object source, ElapsedEventArgs e) cumulus.LogMessage($"GetWllCurrent: Error: {ex.InnerException.Message}"); Thread.Sleep(1000); } - retry = 9; } while (retry < 3); cumulus.LogDebugMessage("GetWllCurrent: Releasing lock"); @@ -1147,13 +1147,13 @@ private void PrintService(char startChar, ServiceAnnouncement service) { ipaddr = service.Addresses[0].ToString(); cumulus.LogMessage($"WLL found, reporting its IP address as: {ipaddr}"); - if (cumulus.VP2IPAddr != ipaddr) + if (cumulus.DavisOptions.IPAddr != ipaddr) { - cumulus.LogMessage($"WLL IP address has changed from {cumulus.VP2IPAddr} to {ipaddr}"); + cumulus.LogMessage($"WLL IP address has changed from {cumulus.DavisOptions.IPAddr} to {ipaddr}"); if (cumulus.WLLAutoUpdateIpAddress) { cumulus.LogMessage($"WLL changing Cumulus config to the new IP address {ipaddr}"); - cumulus.VP2IPAddr = ipaddr; + cumulus.DavisOptions.IPAddr = ipaddr; cumulus.WriteIniFile(); } else @@ -1178,7 +1178,7 @@ private double ConvertRainClicksToUser(double clicks, int size) case 4: return ConvertRainINToUser(clicks * 0.001); default: - switch (cumulus.VPrainGaugeType) + switch (cumulus.DavisOptions.RainGaugeType) { // Hmm, no valid tip size from WLL... // One click is normally either 0.01 inches or 0.2 mm @@ -1846,7 +1846,7 @@ private void DecodeHistoric(int dataType, int sensorType, string json) // add in 'archivePeriod' minutes worth of wind speed to windrun int interval = data11.arch_int / 60; - WindRunToday += ((WindAverage * WindRunHourMult[cumulus.WindUnit] * interval) / 60.0); + WindRunToday += ((WindAverage * WindRunHourMult[cumulus.Units.Wind] * interval) / 60.0); } catch (Exception ex) { diff --git a/CumulusMX/EasyWeather.cs b/CumulusMX/EasyWeather.cs index 2e344f4a..5e8c5f93 100644 --- a/CumulusMX/EasyWeather.cs +++ b/CumulusMX/EasyWeather.cs @@ -83,13 +83,13 @@ public override void portDataReceived(object sender, SerialDataReceivedEventArgs public override void Start() { tmrDataRead.Elapsed += EWGetData; - tmrDataRead.Interval = cumulus.EWInterval*60*1000; + tmrDataRead.Interval = cumulus.EwOptions.Interval*60*1000; tmrDataRead.Enabled = true; DoDayResetIfNeeded(); DoTrendValues(DateTime.Now); - if (File.Exists(cumulus.EWFile)) + if (File.Exists(cumulus.EwOptions.Filename)) { EWGetData(null, null); cumulus.StartTimersAndSensors(); @@ -104,12 +104,12 @@ public override void Stop() private void EWGetData(object sender, ElapsedEventArgs elapsedEventArgs) { - if (File.Exists(cumulus.EWFile)) + if (File.Exists(cumulus.EwOptions.Filename)) { try { string line; - using (FileStream fs = new FileStream(cumulus.EWFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + using (FileStream fs = new FileStream(cumulus.EwOptions.Filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (var sr = new StreamReader(fs)) { do diff --git a/CumulusMX/ExtraSensorSettings.cs b/CumulusMX/ExtraSensorSettings.cs index 6a00286f..99403481 100644 --- a/CumulusMX/ExtraSensorSettings.cs +++ b/CumulusMX/ExtraSensorSettings.cs @@ -23,7 +23,6 @@ public string GetExtraSensorAlpacaFormData() { var indoor = new JsonExtraSensorAirLinkDevice() { - enabled = cumulus.AirLinkInEnabled, ipAddress = cumulus.AirLinkInIPAddr, hostname = cumulus.AirLinkInHostName, isNode = cumulus.AirLinkInIsNode, @@ -32,7 +31,6 @@ public string GetExtraSensorAlpacaFormData() var outdoor = new JsonExtraSensorAirLinkDevice() { - enabled = cumulus.AirLinkOutEnabled, ipAddress = cumulus.AirLinkOutIPAddr, hostname = cumulus.AirLinkOutHostName, isNode = cumulus.AirLinkOutIsNode, @@ -44,7 +42,9 @@ public string GetExtraSensorAlpacaFormData() apiKey = cumulus.AirLinkApiKey, apiSecret = cumulus.AirLinkApiSecret, autoUpdateIp = cumulus.AirLinkAutoUpdateIpAddress, + indoorenabled = cumulus.AirLinkInEnabled, indoor = indoor, + outdoorenabled = cumulus.AirLinkOutEnabled, outdoor = outdoor }; @@ -71,7 +71,9 @@ public string GetExtraSensorAlpacaFormData() var rg11 = new JsonExtraSensorRG11() { + dev1enabled = cumulus.RG11Enabled, port1 = rg11port1, + dev2enabled = cumulus.RG11Enabled2, port2 = rg11port2 }; @@ -125,24 +127,29 @@ public string UpdateExtraSensorConfig(IHttpContext context) cumulus.AirLinkApiSecret = settings.airLink.apiSecret; cumulus.AirLinkAutoUpdateIpAddress = settings.airLink.autoUpdateIp; - cumulus.AirLinkInEnabled = settings.airLink.indoor.enabled; - cumulus.AirLinkInIsNode = settings.airLink.indoor.isNode; - cumulus.AirLinkInIPAddr = settings.airLink.indoor.ipAddress; - cumulus.AirLinkInHostName = settings.airLink.indoor.hostname; - cumulus.AirLinkInStationId = settings.airLink.indoor.stationId; - if (cumulus.AirLinkInStationId < 10 && cumulus.AirLinkInIsNode) + cumulus.AirLinkInEnabled = settings.airLink.indoorenabled; + if (cumulus.AirLinkInEnabled && settings.airLink.indoor != null) { - cumulus.AirLinkInStationId = cumulus.WllStationId; + cumulus.AirLinkInIsNode = settings.airLink.indoor.isNode; + cumulus.AirLinkInIPAddr = settings.airLink.indoor.ipAddress; + cumulus.AirLinkInHostName = settings.airLink.indoor.hostname; + cumulus.AirLinkInStationId = settings.airLink.indoor.stationId; + if (cumulus.AirLinkInStationId < 10 && cumulus.AirLinkInIsNode) + { + cumulus.AirLinkInStationId = cumulus.WllStationId; + } } - - cumulus.AirLinkOutEnabled = settings.airLink.outdoor.enabled; - cumulus.AirLinkOutIsNode = settings.airLink.outdoor.isNode; - cumulus.AirLinkOutIPAddr = settings.airLink.outdoor.ipAddress; - cumulus.AirLinkOutHostName = settings.airLink.outdoor.hostname; - cumulus.AirLinkOutStationId = settings.airLink.outdoor.stationId; - if (cumulus.AirLinkOutStationId < 10 && cumulus.AirLinkOutIsNode) + cumulus.AirLinkOutEnabled = settings.airLink.outdoorenabled; + if (cumulus.AirLinkOutEnabled && settings.airLink.outdoor != null) { - cumulus.AirLinkOutStationId = cumulus.WllStationId; + cumulus.AirLinkOutIsNode = settings.airLink.outdoor.isNode; + cumulus.AirLinkOutIPAddr = settings.airLink.outdoor.ipAddress; + cumulus.AirLinkOutHostName = settings.airLink.outdoor.hostname; + cumulus.AirLinkOutStationId = settings.airLink.outdoor.stationId; + if (cumulus.AirLinkOutStationId < 10 && cumulus.AirLinkOutIsNode) + { + cumulus.AirLinkOutStationId = cumulus.WllStationId; + } } } catch (Exception ex) @@ -169,17 +176,25 @@ public string UpdateExtraSensorConfig(IHttpContext context) // RG-11 settings try { - cumulus.RG11Port = settings.rg11.port1.commPort; - cumulus.RG11TBRmode = settings.rg11.port1.tipMode; - cumulus.RG11tipsize = settings.rg11.port1.tipSize; - cumulus.RG11IgnoreFirst = settings.rg11.port1.ignoreFirst; - cumulus.RG11DTRmode = settings.rg11.port1.dtrMode; - - cumulus.RG11Port2 = settings.rg11.port2.commPort; - cumulus.RG11TBRmode2 = settings.rg11.port2.tipMode; - cumulus.RG11tipsize2 = settings.rg11.port2.tipSize; - cumulus.RG11IgnoreFirst2 = settings.rg11.port2.ignoreFirst; - cumulus.RG11DTRmode2 = settings.rg11.port2.dtrMode; + cumulus.RG11Enabled = settings.rg11.dev1enabled; + if (cumulus.RG11Enabled && settings.rg11.port1 != null) + { + cumulus.RG11Port = settings.rg11.port1.commPort; + cumulus.RG11TBRmode = settings.rg11.port1.tipMode; + cumulus.RG11tipsize = settings.rg11.port1.tipSize; + cumulus.RG11IgnoreFirst = settings.rg11.port1.ignoreFirst; + cumulus.RG11DTRmode = settings.rg11.port1.dtrMode; + } + + cumulus.RG11Enabled2 = settings.rg11.dev2enabled; + if (cumulus.RG11Enabled2 && settings.rg11.port2 != null) + { + cumulus.RG11Port2 = settings.rg11.port2.commPort; + cumulus.RG11TBRmode2 = settings.rg11.port2.tipMode; + cumulus.RG11tipsize2 = settings.rg11.port2.tipSize; + cumulus.RG11IgnoreFirst2 = settings.rg11.port2.ignoreFirst; + cumulus.RG11DTRmode2 = settings.rg11.port2.dtrMode; + } } catch (Exception ex) { @@ -238,13 +253,14 @@ public class JsonExtraSensorAirLinkSettings public string apiKey { get; set; } public string apiSecret { get; set; } public bool autoUpdateIp { get; set; } + public bool indoorenabled { get; set; } public JsonExtraSensorAirLinkDevice indoor { get; set; } + public bool outdoorenabled { get; set; } public JsonExtraSensorAirLinkDevice outdoor { get; set; } } public class JsonExtraSensorAirLinkDevice { - public bool enabled { get; set; } public string ipAddress { get; set; } public string hostname { get; set; } public bool isNode { get; set; } @@ -259,13 +275,14 @@ public class JsonExtraSensorBlakeLarsen public class JsonExtraSensorRG11 { + public bool dev1enabled { get; set; } public JsonExtraSensorRG11device port1 { get; set; } + public bool dev2enabled { get; set; } public JsonExtraSensorRG11device port2 { get; set; } } public class JsonExtraSensorRG11device { - public bool enabled { get; set; } public string commPort { get; set; } public bool tipMode { get; set; } public double tipSize { get; set; } diff --git a/CumulusMX/FOStation.cs b/CumulusMX/FOStation.cs index b1afa94b..8ad42ad7 100644 --- a/CumulusMX/FOStation.cs +++ b/CumulusMX/FOStation.cs @@ -98,11 +98,11 @@ internal FOStation(Cumulus cumulus) : base(cumulus) cumulus.LogMessage("Rel pressure = " + relpressure); cumulus.LogMessage("Abs pressure = " + abspressure); cumulus.LogMessage("Calculated Offset = " + pressureOffset); - if (cumulus.EWpressureoffset < 9999.0) + if (cumulus.EwOptions.PressOffset < 9999.0) { cumulus.LogMessage("Ignoring calculated offset, using offset value from cumulus.ini file"); - cumulus.LogMessage("EWpressureoffset = " + cumulus.EWpressureoffset); - pressureOffset = cumulus.EWpressureoffset; + cumulus.LogMessage("EWpressureoffset = " + cumulus.EwOptions.PressOffset); + pressureOffset = cumulus.EwOptions.PressOffset; } // Read the data from the logger @@ -365,7 +365,7 @@ private void ProcessHistoryData() // Pressure ============================================================= - if ((historydata.pressure < cumulus.EWminpressureMB) || (historydata.pressure > cumulus.EWmaxpressureMB)) + if ((historydata.pressure < cumulus.EwOptions.MinPressMB) || (historydata.pressure > cumulus.EwOptions.MaxPressMB)) { cumulus.LogMessage("Ignoring bad data: pressure = " + historydata.pressure); cumulus.LogMessage(" offset = " + pressureOffset); @@ -510,10 +510,10 @@ private void ProcessHistoryData() } } // add in 'following interval' minutes worth of wind speed to windrun - cumulus.LogMessage("Windrun: " + WindAverage.ToString(cumulus.WindFormat) + cumulus.WindUnitText + " for " + historydata.followinginterval + " minutes = " + - (WindAverage*WindRunHourMult[cumulus.WindUnit]*historydata.followinginterval/60.0).ToString(cumulus.WindRunFormat) + cumulus.WindRunUnitText); + cumulus.LogMessage("Windrun: " + WindAverage.ToString(cumulus.WindFormat) + cumulus.Units.WindText + " for " + historydata.followinginterval + " minutes = " + + (WindAverage*WindRunHourMult[cumulus.Units.Wind]*historydata.followinginterval/60.0).ToString(cumulus.WindRunFormat) + cumulus.Units.WindRunText); - WindRunToday += (WindAverage*WindRunHourMult[cumulus.WindUnit]*historydata.followinginterval/60.0); + WindRunToday += (WindAverage*WindRunHourMult[cumulus.Units.Wind]*historydata.followinginterval/60.0); // update heating/cooling degree days UpdateDegreeDays(historydata.interval); @@ -591,7 +591,7 @@ private void ReadAddress(int address, byte[] buff) //response = device.WriteRead(0x00, request); stream.Write(request); - Thread.Sleep(cumulus.FineOffsetReadTime); + Thread.Sleep(cumulus.FineOffsetOptions.FineOffsetReadTime); for (int i = 1; i < 5; i++) { //cumulus.LogMessage("Reading 8 bytes"); @@ -660,7 +660,7 @@ private void GetAndProcessData() var data = new byte[32]; - if (cumulus.StationOptions.SyncFOReads && !synchronising) + if (cumulus.FineOffsetOptions.FineOffsetSyncReads && !synchronising) { if ((DateTime.Now - FOSensorClockTime).TotalDays > 1) { @@ -672,21 +672,21 @@ private void GetAndProcessData() } // Check that were not within N seconds of the station updating memory - bool sensorclockOK = ((int)(Math.Floor((DateTime.Now - FOSensorClockTime).TotalSeconds))%48 >= (cumulus.FOReadAvoidPeriod - 1)) && - ((int)(Math.Floor((DateTime.Now - FOSensorClockTime).TotalSeconds))%48 <= (47 - cumulus.FOReadAvoidPeriod)); - bool stationclockOK = ((int)(Math.Floor((DateTime.Now - FOStationClockTime).TotalSeconds))%60 >= (cumulus.FOReadAvoidPeriod - 1)) && - ((int)(Math.Floor((DateTime.Now - FOStationClockTime).TotalSeconds))%60 <= (59 - cumulus.FOReadAvoidPeriod)); + bool sensorclockOK = ((int)(Math.Floor((DateTime.Now - FOSensorClockTime).TotalSeconds))%48 >= (cumulus.FineOffsetOptions.FineOffsetReadAvoidPeriod - 1)) && + ((int)(Math.Floor((DateTime.Now - FOSensorClockTime).TotalSeconds))%48 <= (47 - cumulus.FineOffsetOptions.FineOffsetReadAvoidPeriod)); + bool stationclockOK = ((int)(Math.Floor((DateTime.Now - FOStationClockTime).TotalSeconds))%60 >= (cumulus.FineOffsetOptions.FineOffsetReadAvoidPeriod - 1)) && + ((int)(Math.Floor((DateTime.Now - FOStationClockTime).TotalSeconds))%60 <= (59 - cumulus.FineOffsetOptions.FineOffsetReadAvoidPeriod)); if (!sensorclockOK || !stationclockOK) { if (!sensorclockOK) { - cumulus.LogDebugMessage("Within "+cumulus.FOReadAvoidPeriod+" seconds of sensor data change, skipping read"); + cumulus.LogDebugMessage("Within "+cumulus.FineOffsetOptions.FineOffsetReadAvoidPeriod +" seconds of sensor data change, skipping read"); } if (!stationclockOK) { - cumulus.LogDebugMessage("Within " + cumulus.FOReadAvoidPeriod + " seconds of station clock minute change, skipping read"); + cumulus.LogDebugMessage("Within " + cumulus.FineOffsetOptions.FineOffsetReadAvoidPeriod + " seconds of station clock minute change, skipping read"); } return; @@ -809,7 +809,7 @@ private void GetAndProcessData() // Pressure ========================================================= double pressure = (data[7] + ((data[8] & 0x3f)*256))/10.0f + pressureOffset; - if ((pressure < cumulus.EWminpressureMB) || (pressure > cumulus.EWmaxpressureMB)) + if ((pressure < cumulus.EwOptions.MinPressMB) || (pressure > cumulus.EwOptions.MaxPressMB)) { // bad value cumulus.LogMessage("Ignoring bad data: pressure = " + pressure); @@ -933,7 +933,7 @@ private void GetAndProcessData() int raindiff = Math.Abs(raintot - prevraintotal); - if (raindiff > cumulus.EWMaxRainTipDiff) + if (raindiff > cumulus.EwOptions.MaxRainTipDiff) { cumulus.LogMessage("Warning: large difference in rain gauge tip count: " + raindiff); diff --git a/CumulusMX/ImetStation.cs b/CumulusMX/ImetStation.cs index f4f6b889..2dbd3f5c 100644 --- a/CumulusMX/ImetStation.cs +++ b/CumulusMX/ImetStation.cs @@ -22,21 +22,21 @@ internal class ImetStation : WeatherStation public ImetStation(Cumulus cumulus) : base(cumulus) { cumulus.Manufacturer = cumulus.INSTROMET; - cumulus.LogMessage("ImetUpdateLogPointer=" + cumulus.ImetUpdateLogPointer); - cumulus.LogMessage("ImetWaitTime=" + cumulus.ImetWaitTime); - cumulus.LogMessage("ImetReadDelay=" + cumulus.ImetReadDelay); - cumulus.LogMessage("ImetBaudRate=" + cumulus.ImetBaudRate); + cumulus.LogMessage("ImetUpdateLogPointer=" + cumulus.ImetOptions.ImetUpdateLogPointer); + cumulus.LogMessage("ImetWaitTime=" + cumulus.ImetOptions.ImetWaitTime); + cumulus.LogMessage("ImetReadDelay=" + cumulus.ImetOptions.ImetReadDelay); + cumulus.LogMessage("ImetOptions.ImetBaudRate=" + cumulus.ImetOptions.ImetBaudRate); cumulus.LogMessage("Instromet: Attempting to open " + cumulus.ComportName); calculaterainrate = true; // Change the default dps for rain and sunshine from 1 to 2 for IMet stations cumulus.RainDPlaces = cumulus.SunshineDPlaces = 2; - cumulus.RainDPlace[0] = 2; // mm - cumulus.RainDPlace[1] = 3; // in + cumulus.RainDPlaceDefaults[0] = 2; // mm + cumulus.RainDPlaceDefaults[1] = 3; // in cumulus.RainFormat = cumulus.SunFormat = "F2"; - comport = new SerialPort(cumulus.ComportName, cumulus.ImetBaudRate, Parity.None, 8, StopBits.One) {Handshake = Handshake.None, RtsEnable = true, DtrEnable = true}; + comport = new SerialPort(cumulus.ComportName, cumulus.ImetOptions.ImetBaudRate, Parity.None, 8, StopBits.One) {Handshake = Handshake.None, RtsEnable = true, DtrEnable = true}; try { @@ -247,7 +247,7 @@ private void SendCommand(string command) } finally { - Thread.Sleep(cumulus.ImetWaitTime); + Thread.Sleep(cumulus.ImetOptions.ImetWaitTime); } } @@ -665,7 +665,7 @@ public override void getAndProcessHistoryData() DoWind(windgust, windbearing, windspeed, timestamp); // add in "archivePeriod" minutes worth of wind speed to windrun - WindRunToday += ((WindAverage*WindRunHourMult[cumulus.WindUnit]*interval)/60.0); + WindRunToday += ((WindAverage*WindRunHourMult[cumulus.Units.Wind]*interval)/60.0); DateTime windruncheckTS; if ((hour == rollHour) && (minute == 0)) @@ -838,7 +838,7 @@ public override void Start() } else { - Thread.Sleep(cumulus.ImetReadDelay); + Thread.Sleep(cumulus.ImetOptions.ImetReadDelay); } } } @@ -873,7 +873,7 @@ private void ImetGetData() { previousminute = min; - if (cumulus.StationOptions.SyncTime && (h == cumulus.ClockSettingHour) && (min == 0)) + if (cumulus.StationOptions.SyncTime && (h == cumulus.StationOptions.ClockSettingHour) && (min == 0)) { // It's 0400, set the station clock SetStationClock(); @@ -1017,7 +1017,7 @@ private void ImetGetData() cumulus.LogMessage(response); } - if (!cumulus.ImetUpdateLogPointer || stop) + if (!cumulus.ImetOptions.ImetUpdateLogPointer || stop) return; // Keep the log pointer current, to avoid large numbers of logs diff --git a/CumulusMX/InternetSettings.cs b/CumulusMX/InternetSettings.cs index c2e59033..eb95df82 100644 --- a/CumulusMX/InternetSettings.cs +++ b/CumulusMX/InternetSettings.cs @@ -77,7 +77,6 @@ public string UpdateInternetConfig(IHttpContext context) cumulus.FTPRename = settings.websettings.ftprename; cumulus.IncludeStandardFiles = settings.websettings.includestdfiles; cumulus.IncludeGraphDataFiles = settings.websettings.includegraphdatafiles; - cumulus.IncludeMoonImage = settings.websettings.includemoonimage; cumulus.UTF8encode = settings.websettings.utf8encode; if (settings.websettings.ftplogging != cumulus.FTPlogging) { @@ -98,12 +97,15 @@ public string UpdateInternetConfig(IHttpContext context) // external programs try { - cumulus.DailyProgram = settings.externalprograms.dailyprogram ?? string.Empty; - cumulus.DailyParams = settings.externalprograms.dailyprogramparams ?? string.Empty; - cumulus.ExternalProgram = settings.externalprograms.program ?? string.Empty; - cumulus.ExternalParams = settings.externalprograms.programparams ?? string.Empty; - cumulus.RealtimeProgram = settings.externalprograms.realtimeprogram ?? string.Empty; - cumulus.RealtimeParams = settings.externalprograms.realtimeprogramparams ?? string.Empty; + if (settings.externalprograms != null) + { + cumulus.DailyProgram = settings.externalprograms.dailyprogram ?? string.Empty; + cumulus.DailyParams = settings.externalprograms.dailyprogramparams ?? string.Empty; + cumulus.ExternalProgram = settings.externalprograms.program ?? string.Empty; + cumulus.ExternalParams = settings.externalprograms.programparams ?? string.Empty; + cumulus.RealtimeProgram = settings.externalprograms.realtimeprogram ?? string.Empty; + cumulus.RealtimeParams = settings.externalprograms.realtimeprogramparams ?? string.Empty; + } } catch (Exception ex) { @@ -117,14 +119,17 @@ public string UpdateInternetConfig(IHttpContext context) try { cumulus.Twitter.Enabled = settings.twitter.enabled; - cumulus.Twitter.Interval = settings.twitter.interval; - cumulus.Twitter.PW = settings.twitter.password ?? string.Empty; - cumulus.Twitter.SendLocation = settings.twitter.sendlocation; - cumulus.Twitter.ID = settings.twitter.user ?? string.Empty; - cumulus.Twitter.SynchronisedUpdate = (60 % cumulus.Twitter.Interval == 0); - - cumulus.TwitterTimer.Interval = cumulus.Twitter.Interval * 60 * 1000; - cumulus.TwitterTimer.Enabled = cumulus.Twitter.Enabled && !cumulus.Twitter.SynchronisedUpdate && !string.IsNullOrWhiteSpace(cumulus.Twitter.ID) && !string.IsNullOrWhiteSpace(cumulus.Twitter.PW); + if (cumulus.Twitter.Enabled) + { + cumulus.Twitter.Interval = settings.twitter.interval; + cumulus.Twitter.PW = settings.twitter.password ?? string.Empty; + cumulus.Twitter.SendLocation = settings.twitter.sendlocation; + cumulus.Twitter.ID = settings.twitter.user ?? string.Empty; + cumulus.Twitter.SynchronisedUpdate = (60 % cumulus.Twitter.Interval == 0); + + cumulus.TwitterTimer.Interval = cumulus.Twitter.Interval * 60 * 1000; + cumulus.TwitterTimer.Enabled = cumulus.Twitter.Enabled && !cumulus.Twitter.SynchronisedUpdate && !string.IsNullOrWhiteSpace(cumulus.Twitter.ID) && !string.IsNullOrWhiteSpace(cumulus.Twitter.PW); + } } catch (Exception ex) { @@ -137,21 +142,24 @@ public string UpdateInternetConfig(IHttpContext context) // wunderground try { - cumulus.Wund.CatchUp = settings.wunderground.catchup; cumulus.Wund.Enabled = settings.wunderground.enabled; - cumulus.Wund.SendIndoor = settings.wunderground.includeindoor; - cumulus.Wund.SendSolar = settings.wunderground.includesolar; - cumulus.Wund.SendUV = settings.wunderground.includeuv; - cumulus.Wund.SendAirQuality = settings.wunderground.includeaq; - cumulus.Wund.Interval = settings.wunderground.interval; - cumulus.Wund.PW = settings.wunderground.password ?? string.Empty; - cumulus.Wund.RapidFireEnabled = settings.wunderground.rapidfire; - cumulus.Wund.SendAverage = settings.wunderground.sendavgwind; - cumulus.Wund.ID = settings.wunderground.stationid ?? string.Empty; - cumulus.Wund.SynchronisedUpdate = (!cumulus.Wund.RapidFireEnabled) && (60 % cumulus.Wund.Interval == 0); - - cumulus.WundTimer.Interval = cumulus.Wund.RapidFireEnabled ? 5000 : cumulus.Wund.Interval * 60 * 1000; - cumulus.WundTimer.Enabled = cumulus.Wund.Enabled && !cumulus.Wund.SynchronisedUpdate && !string.IsNullOrWhiteSpace(cumulus.Wund.ID) && !string.IsNullOrWhiteSpace(cumulus.Wund.PW); + if (cumulus.Wund.Enabled) + { + cumulus.Wund.SendIndoor = settings.wunderground.includeindoor; + cumulus.Wund.SendSolar = settings.wunderground.includesolar; + cumulus.Wund.SendUV = settings.wunderground.includeuv; + cumulus.Wund.SendAirQuality = settings.wunderground.includeaq; + cumulus.Wund.Interval = settings.wunderground.interval; + cumulus.Wund.PW = settings.wunderground.password ?? string.Empty; + cumulus.Wund.RapidFireEnabled = settings.wunderground.rapidfire; + cumulus.Wund.SendAverage = settings.wunderground.sendavgwind; + cumulus.Wund.ID = settings.wunderground.stationid ?? string.Empty; + cumulus.Wund.CatchUp = settings.wunderground.catchup; + cumulus.Wund.SynchronisedUpdate = (!cumulus.Wund.RapidFireEnabled) && (60 % cumulus.Wund.Interval == 0); + + cumulus.WundTimer.Interval = cumulus.Wund.RapidFireEnabled ? 5000 : cumulus.Wund.Interval * 60 * 1000; + cumulus.WundTimer.Enabled = cumulus.Wund.Enabled && !cumulus.Wund.SynchronisedUpdate && !string.IsNullOrWhiteSpace(cumulus.Wund.ID) && !string.IsNullOrWhiteSpace(cumulus.Wund.PW); + } } catch (Exception ex) { @@ -164,17 +172,20 @@ public string UpdateInternetConfig(IHttpContext context) // Windy try { - cumulus.Windy.CatchUp = settings.windy.catchup; cumulus.Windy.Enabled = settings.windy.enabled; - //cumulus.WindySendSolar = settings.windy.includesolar; - cumulus.Windy.SendUV = settings.windy.includeuv; - cumulus.Windy.Interval = settings.windy.interval; - cumulus.Windy.ApiKey = settings.windy.apikey; - cumulus.Windy.StationIdx = settings.windy.stationidx; - cumulus.Windy.SynchronisedUpdate = (60 % cumulus.Windy.Interval == 0); - - cumulus.WindyTimer.Interval = cumulus.Windy.Interval * 60 * 1000; - cumulus.WindyTimer.Enabled = cumulus.Windy.Enabled && !cumulus.Windy.SynchronisedUpdate && !string.IsNullOrWhiteSpace(cumulus.Windy.ApiKey); + if (cumulus.Windy.Enabled) + { + //cumulus.WindySendSolar = settings.windy.includesolar; + cumulus.Windy.SendUV = settings.windy.includeuv; + cumulus.Windy.Interval = settings.windy.interval; + cumulus.Windy.ApiKey = settings.windy.apikey; + cumulus.Windy.StationIdx = settings.windy.stationidx; + cumulus.Windy.CatchUp = settings.windy.catchup; + cumulus.Windy.SynchronisedUpdate = (60 % cumulus.Windy.Interval == 0); + + cumulus.WindyTimer.Interval = cumulus.Windy.Interval * 60 * 1000; + cumulus.WindyTimer.Enabled = cumulus.Windy.Enabled && !cumulus.Windy.SynchronisedUpdate && !string.IsNullOrWhiteSpace(cumulus.Windy.ApiKey); + } } catch (Exception ex) { @@ -188,21 +199,24 @@ public string UpdateInternetConfig(IHttpContext context) try { cumulus.AWEKAS.Enabled = settings.awekas.enabled; - cumulus.AWEKAS.Interval = settings.awekas.interval; - cumulus.AWEKAS.Lang = settings.awekas.lang; - cumulus.AWEKAS.PW = settings.awekas.password ?? string.Empty; - cumulus.AWEKAS.ID = settings.awekas.user ?? string.Empty; - cumulus.AWEKAS.SendSolar = settings.awekas.includesolar; - cumulus.AWEKAS.SendUV = settings.awekas.includeuv; - cumulus.AWEKAS.SendSoilTemp = settings.awekas.includesoiltemp; - cumulus.AWEKAS.SendSoilMoisture = settings.awekas.includesoilmoisture; - cumulus.AWEKAS.SendLeafWetness = settings.awekas.includeleafwetness; - cumulus.AWEKAS.SendIndoor = settings.awekas.includeindoor; - cumulus.AWEKAS.SendAirQuality = settings.awekas.includeaq; - cumulus.AWEKAS.SynchronisedUpdate = (cumulus.AWEKAS.Interval % 60 == 0); - - cumulus.AwekasTimer.Interval = cumulus.AWEKAS.Interval * 1000; - cumulus.AwekasTimer.Enabled = cumulus.AWEKAS.Enabled && !cumulus.AWEKAS.SynchronisedUpdate && !string.IsNullOrWhiteSpace(cumulus.AWEKAS.ID) && !string.IsNullOrWhiteSpace(cumulus.AWEKAS.PW); + if (cumulus.AWEKAS.Enabled) + { + cumulus.AWEKAS.Interval = settings.awekas.interval; + cumulus.AWEKAS.Lang = settings.awekas.lang; + cumulus.AWEKAS.PW = settings.awekas.password ?? string.Empty; + cumulus.AWEKAS.ID = settings.awekas.user ?? string.Empty; + cumulus.AWEKAS.SendSolar = settings.awekas.includesolar; + cumulus.AWEKAS.SendUV = settings.awekas.includeuv; + cumulus.AWEKAS.SendSoilTemp = settings.awekas.includesoiltemp; + cumulus.AWEKAS.SendSoilMoisture = settings.awekas.includesoilmoisture; + cumulus.AWEKAS.SendLeafWetness = settings.awekas.includeleafwetness; + cumulus.AWEKAS.SendIndoor = settings.awekas.includeindoor; + cumulus.AWEKAS.SendAirQuality = settings.awekas.includeaq; + cumulus.AWEKAS.SynchronisedUpdate = (cumulus.AWEKAS.Interval % 60 == 0); + + cumulus.AwekasTimer.Interval = cumulus.AWEKAS.Interval * 1000; + cumulus.AwekasTimer.Enabled = cumulus.AWEKAS.Enabled && !cumulus.AWEKAS.SynchronisedUpdate && !string.IsNullOrWhiteSpace(cumulus.AWEKAS.ID) && !string.IsNullOrWhiteSpace(cumulus.AWEKAS.PW); + } } catch (Exception ex) { @@ -215,15 +229,18 @@ public string UpdateInternetConfig(IHttpContext context) // WeatherCloud try { - cumulus.WCloud.ID = settings.weathercloud.wid ?? string.Empty; - cumulus.WCloud.PW = settings.weathercloud.key ?? string.Empty; cumulus.WCloud.Enabled = settings.weathercloud.enabled; - cumulus.WCloud.SendSolar = settings.weathercloud.includesolar; - cumulus.WCloud.SendUV = settings.weathercloud.includeuv; - cumulus.WCloud.SynchronisedUpdate = (60 % cumulus.WCloud.Interval == 0); - - cumulus.WCloudTimer.Interval = cumulus.WCloud.Interval * 60 * 1000; - cumulus.WCloudTimer.Enabled = cumulus.WCloud.Enabled && !cumulus.WCloud.SynchronisedUpdate && !String.IsNullOrWhiteSpace(cumulus.WCloud.ID) && !String.IsNullOrWhiteSpace(cumulus.WCloud.PW); + if (cumulus.WCloud.Enabled) + { + cumulus.WCloud.ID = settings.weathercloud.wid ?? string.Empty; + cumulus.WCloud.PW = settings.weathercloud.key ?? string.Empty; + cumulus.WCloud.SendSolar = settings.weathercloud.includesolar; + cumulus.WCloud.SendUV = settings.weathercloud.includeuv; + cumulus.WCloud.SynchronisedUpdate = (60 % cumulus.WCloud.Interval == 0); + + cumulus.WCloudTimer.Interval = cumulus.WCloud.Interval * 60 * 1000; + cumulus.WCloudTimer.Enabled = cumulus.WCloud.Enabled && !cumulus.WCloud.SynchronisedUpdate && !String.IsNullOrWhiteSpace(cumulus.WCloud.ID) && !String.IsNullOrWhiteSpace(cumulus.WCloud.PW); + } } catch (Exception ex) { @@ -236,17 +253,20 @@ public string UpdateInternetConfig(IHttpContext context) // PWS weather try { - cumulus.PWS.CatchUp = settings.pwsweather.catchup; cumulus.PWS.Enabled = settings.pwsweather.enabled; - cumulus.PWS.Interval = settings.pwsweather.interval; - cumulus.PWS.SendSolar = settings.pwsweather.includesolar; - cumulus.PWS.SendUV = settings.pwsweather.includeuv; - cumulus.PWS.PW = settings.pwsweather.password ?? string.Empty; - cumulus.PWS.ID = settings.pwsweather.stationid ?? string.Empty; - cumulus.PWS.SynchronisedUpdate = (60 % cumulus.PWS.Interval == 0); - - cumulus.PWSTimer.Interval = cumulus.PWS.Interval * 60 * 1000; - cumulus.PWSTimer.Enabled = cumulus.PWS.Enabled && !cumulus.PWS.SynchronisedUpdate && !string.IsNullOrWhiteSpace(cumulus.PWS.ID) && !string.IsNullOrWhiteSpace(cumulus.PWS.PW); + if (cumulus.PWS.Enabled) + { + cumulus.PWS.Interval = settings.pwsweather.interval; + cumulus.PWS.SendSolar = settings.pwsweather.includesolar; + cumulus.PWS.SendUV = settings.pwsweather.includeuv; + cumulus.PWS.PW = settings.pwsweather.password ?? string.Empty; + cumulus.PWS.ID = settings.pwsweather.stationid ?? string.Empty; + cumulus.PWS.CatchUp = settings.pwsweather.catchup; + cumulus.PWS.SynchronisedUpdate = (60 % cumulus.PWS.Interval == 0); + + cumulus.PWSTimer.Interval = cumulus.PWS.Interval * 60 * 1000; + cumulus.PWSTimer.Enabled = cumulus.PWS.Enabled && !cumulus.PWS.SynchronisedUpdate && !string.IsNullOrWhiteSpace(cumulus.PWS.ID) && !string.IsNullOrWhiteSpace(cumulus.PWS.PW); + } } catch (Exception ex) { @@ -259,17 +279,20 @@ public string UpdateInternetConfig(IHttpContext context) // WOW try { - cumulus.WOW.CatchUp = settings.wow.catchup; cumulus.WOW.Enabled = settings.wow.enabled; - cumulus.WOW.SendSolar = settings.wow.includesolar; - cumulus.WOW.SendUV = settings.wow.includeuv; - cumulus.WOW.Interval = settings.wow.interval; - cumulus.WOW.PW = settings.wow.password ?? string.Empty; ; - cumulus.WOW.ID = settings.wow.stationid ?? string.Empty; ; - cumulus.WOW.SynchronisedUpdate = (60 % cumulus.WOW.Interval == 0); - - cumulus.WOWTimer.Interval = cumulus.WOW.Interval * 60 * 1000; - cumulus.WOWTimer.Enabled = cumulus.WOW.Enabled && !cumulus.WOW.SynchronisedUpdate && !string.IsNullOrWhiteSpace(cumulus.WOW.ID) && !string.IsNullOrWhiteSpace(cumulus.WOW.PW); + if (cumulus.WOW.Enabled) + { + cumulus.WOW.SendSolar = settings.wow.includesolar; + cumulus.WOW.SendUV = settings.wow.includeuv; + cumulus.WOW.Interval = settings.wow.interval; + cumulus.WOW.PW = settings.wow.password ?? string.Empty; ; + cumulus.WOW.ID = settings.wow.stationid ?? string.Empty; ; + cumulus.WOW.CatchUp = settings.wow.catchup; + cumulus.WOW.SynchronisedUpdate = (60 % cumulus.WOW.Interval == 0); + + cumulus.WOWTimer.Interval = cumulus.WOW.Interval * 60 * 1000; + cumulus.WOWTimer.Enabled = cumulus.WOW.Enabled && !cumulus.WOW.SynchronisedUpdate && !string.IsNullOrWhiteSpace(cumulus.WOW.ID) && !string.IsNullOrWhiteSpace(cumulus.WOW.PW); + } } catch (Exception ex) { @@ -283,16 +306,19 @@ public string UpdateInternetConfig(IHttpContext context) try { cumulus.APRS.Enabled = settings.cwop.enabled; - cumulus.APRS.ID = settings.cwop.id ?? string.Empty; ; - cumulus.APRS.Interval = settings.cwop.interval; - cumulus.APRS.SendSolar = settings.cwop.includesolar; - cumulus.APRS.PW = settings.cwop.password ?? string.Empty; ; - cumulus.APRS.Port = settings.cwop.port; - cumulus.APRS.Server = settings.cwop.server ?? string.Empty; ; - cumulus.APRS.SynchronisedUpdate = (60 % cumulus.APRS.Interval == 0); - - cumulus.APRStimer.Interval = cumulus.APRS.Interval * 60 * 1000; - cumulus.APRStimer.Enabled = cumulus.APRS.Enabled && !cumulus.APRS.SynchronisedUpdate && !string.IsNullOrWhiteSpace(cumulus.APRS.ID) && !string.IsNullOrWhiteSpace(cumulus.APRS.PW); + if (cumulus.APRS.Enabled) + { + cumulus.APRS.ID = settings.cwop.id ?? string.Empty; ; + cumulus.APRS.Interval = settings.cwop.interval; + cumulus.APRS.SendSolar = settings.cwop.includesolar; + cumulus.APRS.PW = settings.cwop.password ?? string.Empty; ; + cumulus.APRS.Port = settings.cwop.port; + cumulus.APRS.Server = settings.cwop.server ?? string.Empty; ; + cumulus.APRS.SynchronisedUpdate = (60 % cumulus.APRS.Interval == 0); + + cumulus.APRStimer.Interval = cumulus.APRS.Interval * 60 * 1000; + cumulus.APRStimer.Enabled = cumulus.APRS.Enabled && !cumulus.APRS.SynchronisedUpdate && !string.IsNullOrWhiteSpace(cumulus.APRS.ID) && !string.IsNullOrWhiteSpace(cumulus.APRS.PW); + } } catch (Exception ex) { @@ -306,14 +332,17 @@ public string UpdateInternetConfig(IHttpContext context) try { cumulus.OpenWeatherMap.Enabled = settings.openweathermap.enabled; - cumulus.OpenWeatherMap.CatchUp = settings.openweathermap.catchup; - cumulus.OpenWeatherMap.PW = settings.openweathermap.apikey; - cumulus.OpenWeatherMap.ID = settings.openweathermap.stationid; - cumulus.OpenWeatherMap.Interval = settings.openweathermap.interval; - cumulus.OpenWeatherMap.SynchronisedUpdate = (60 % cumulus.OpenWeatherMap.Interval == 0); - - cumulus.OpenWeatherMapTimer.Interval = cumulus.OpenWeatherMap.Interval * 60 * 1000; - cumulus.OpenWeatherMapTimer.Enabled = cumulus.OpenWeatherMap.Enabled && !string.IsNullOrWhiteSpace(cumulus.OpenWeatherMap.PW); + if (cumulus.OpenWeatherMap.Enabled) + { + cumulus.OpenWeatherMap.CatchUp = settings.openweathermap.catchup; + cumulus.OpenWeatherMap.PW = settings.openweathermap.apikey; + cumulus.OpenWeatherMap.ID = settings.openweathermap.stationid; + cumulus.OpenWeatherMap.Interval = settings.openweathermap.interval; + cumulus.OpenWeatherMap.SynchronisedUpdate = (60 % cumulus.OpenWeatherMap.Interval == 0); + + cumulus.OpenWeatherMapTimer.Interval = cumulus.OpenWeatherMap.Interval * 60 * 1000; + cumulus.OpenWeatherMapTimer.Enabled = cumulus.OpenWeatherMap.Enabled && !string.IsNullOrWhiteSpace(cumulus.OpenWeatherMap.PW); + } } catch (Exception ex) { @@ -332,17 +361,23 @@ public string UpdateInternetConfig(IHttpContext context) cumulus.MQTT.Username = settings.mqtt.username ?? string.Empty; cumulus.MQTT.Password = settings.mqtt.password ?? string.Empty; cumulus.MQTT.EnableDataUpdate = settings.mqtt.dataUpdate.enabled; - cumulus.MQTT.UpdateTopic = settings.mqtt.dataUpdate.topic ?? string.Empty; - cumulus.MQTT.UpdateTemplate = settings.mqtt.dataUpdate.template ?? string.Empty; - cumulus.MQTT.UpdateRetained = settings.mqtt.dataUpdate.retained; + if (cumulus.MQTT.EnableDataUpdate) + { + cumulus.MQTT.UpdateTopic = settings.mqtt.dataUpdate.topic ?? string.Empty; + cumulus.MQTT.UpdateTemplate = settings.mqtt.dataUpdate.template ?? string.Empty; + cumulus.MQTT.UpdateRetained = settings.mqtt.dataUpdate.retained; + } cumulus.MQTT.EnableInterval = settings.mqtt.interval.enabled; - cumulus.MQTT.IntervalTime = settings.mqtt.interval.time; - cumulus.MQTT.IntervalTopic = settings.mqtt.interval.topic ?? string.Empty; - cumulus.MQTT.IntervalTemplate = settings.mqtt.interval.template ?? string.Empty; - cumulus.MQTT.IntervalRetained = settings.mqtt.interval.retained; + if (cumulus.MQTT.EnableInterval) + { + cumulus.MQTT.IntervalTime = settings.mqtt.interval.time; + cumulus.MQTT.IntervalTopic = settings.mqtt.interval.topic ?? string.Empty; + cumulus.MQTT.IntervalTemplate = settings.mqtt.interval.template ?? string.Empty; + cumulus.MQTT.IntervalRetained = settings.mqtt.interval.retained; - cumulus.MQTTTimer.Interval = cumulus.MQTT.IntervalTime * 1000; - cumulus.MQTTTimer.Enabled = cumulus.MQTT.EnableInterval && !string.IsNullOrWhiteSpace(cumulus.MQTT.IntervalTopic) && !string.IsNullOrWhiteSpace(cumulus.MQTT.IntervalTemplate); + cumulus.MQTTTimer.Interval = cumulus.MQTT.IntervalTime * 1000; + cumulus.MQTTTimer.Enabled = cumulus.MQTT.EnableInterval && !string.IsNullOrWhiteSpace(cumulus.MQTT.IntervalTopic) && !string.IsNullOrWhiteSpace(cumulus.MQTT.IntervalTemplate); + } } catch (Exception ex) { @@ -356,8 +391,12 @@ public string UpdateInternetConfig(IHttpContext context) try { cumulus.MoonImageEnabled = settings.moonimage.enabled; - cumulus.MoonImageSize = settings.moonimage.size; - cumulus.MoonImageFtpDest = settings.moonimage.ftpdest; + if (cumulus.MoonImageEnabled) + { + cumulus.IncludeMoonImage = settings.moonimage.includemoonimage; + cumulus.MoonImageSize = settings.moonimage.size; + cumulus.MoonImageFtpDest = settings.moonimage.ftpdest; + } } catch (Exception ex) { @@ -387,26 +426,35 @@ public string UpdateInternetConfig(IHttpContext context) try { // custom seconds - cumulus.CustomHttpSecondsString = settings.customhttp.customseconds.url ?? string.Empty; cumulus.CustomHttpSecondsEnabled = settings.customhttp.customseconds.enabled; - cumulus.CustomHttpSecondsInterval = settings.customhttp.customseconds.interval; - cumulus.CustomHttpSecondsTimer.Interval = cumulus.CustomHttpSecondsInterval * 1000; - cumulus.CustomHttpSecondsTimer.Enabled = cumulus.CustomHttpSecondsEnabled; - // custom minutes - cumulus.CustomHttpMinutesString = settings.customhttp.customminutes.url ?? string.Empty; - cumulus.CustomHttpMinutesEnabled = settings.customhttp.customminutes.enabled; - cumulus.CustomHttpMinutesIntervalIndex = settings.customhttp.customminutes.intervalindex; - if (cumulus.CustomHttpMinutesIntervalIndex >= 0 && cumulus.CustomHttpMinutesIntervalIndex < cumulus.FactorsOf60.Length) + if (cumulus.CustomHttpSecondsEnabled) { - cumulus.CustomHttpMinutesInterval = cumulus.FactorsOf60[cumulus.CustomHttpMinutesIntervalIndex]; + cumulus.CustomHttpSecondsString = settings.customhttp.customseconds.url ?? string.Empty; + cumulus.CustomHttpSecondsInterval = settings.customhttp.customseconds.interval; + cumulus.CustomHttpSecondsTimer.Interval = cumulus.CustomHttpSecondsInterval * 1000; + cumulus.CustomHttpSecondsTimer.Enabled = cumulus.CustomHttpSecondsEnabled; } - else + // custom minutes + cumulus.CustomHttpMinutesEnabled = settings.customhttp.customminutes.enabled; + if (cumulus.CustomHttpMinutesEnabled) { - cumulus.CustomHttpMinutesInterval = 10; + cumulus.CustomHttpMinutesString = settings.customhttp.customminutes.url ?? string.Empty; + cumulus.CustomHttpMinutesIntervalIndex = settings.customhttp.customminutes.intervalindex; + if (cumulus.CustomHttpMinutesIntervalIndex >= 0 && cumulus.CustomHttpMinutesIntervalIndex < cumulus.FactorsOf60.Length) + { + cumulus.CustomHttpMinutesInterval = cumulus.FactorsOf60[cumulus.CustomHttpMinutesIntervalIndex]; + } + else + { + cumulus.CustomHttpMinutesInterval = 10; + } } // custom rollover - cumulus.CustomHttpRolloverString = settings.customhttp.customrollover.url ?? string.Empty; cumulus.CustomHttpRolloverEnabled = settings.customhttp.customrollover.enabled; + if (cumulus.CustomHttpRolloverEnabled) + { + cumulus.CustomHttpRolloverString = settings.customhttp.customrollover.url ?? string.Empty; + } } catch (Exception ex) { @@ -489,7 +537,6 @@ public string GetInternetAlpacaFormData() ftprename = cumulus.FTPRename, includestdfiles = cumulus.IncludeStandardFiles, includegraphdatafiles = cumulus.IncludeGraphDataFiles, - includemoonimage = cumulus.IncludeMoonImage, utf8encode = cumulus.UTF8encode, ftplogging = cumulus.FTPlogging }; @@ -636,6 +683,7 @@ public string GetInternetAlpacaFormData() var moonimagesettings = new JsonInternetSettingsMoonImage() { enabled = cumulus.MoonImageEnabled, + includemoonimage = cumulus.IncludeMoonImage, size = cumulus.MoonImageSize, ftpdest = cumulus.MoonImageFtpDest }; @@ -847,7 +895,6 @@ public class JsonInternetSettingsWebSettings public bool autoupdate { get; set; } public bool includestdfiles { get; set; } public bool includegraphdatafiles { get; set; } - public bool includemoonimage { get; set; } public bool activeftp { get; set; } public bool ftprename { get; set; } public bool ftpdelete { get; set; } @@ -1005,6 +1052,7 @@ public class JsonInternetSettingsMqttInterval public class JsonInternetSettingsMoonImage { public bool enabled { get; set; } + public bool includemoonimage { get; set; } public int size { get; set; } public string ftpdest { get; set; } } diff --git a/CumulusMX/MysqlSettings.cs b/CumulusMX/MysqlSettings.cs index 672d00d3..e99bf727 100644 --- a/CumulusMX/MysqlSettings.cs +++ b/CumulusMX/MysqlSettings.cs @@ -23,46 +23,63 @@ public MysqlSettings(Cumulus cumulus) public string GetMySqlAlpacaFormData() { var server = new JsonMysqlSettingsServer() - { - database = cumulus.MySqlDatabase, - host = cumulus.MySqlHost, - pass = cumulus.MySqlPass, - port = cumulus.MySqlPort, - user = cumulus.MySqlUser - }; - - var monthly = new JsonMysqlSettingsMonthly() {enabled = cumulus.MonthlyMySqlEnabled, table = cumulus.MySqlMonthlyTable}; + { + database = cumulus.MySqlDatabase, + host = cumulus.MySqlHost, + pass = cumulus.MySqlPass, + port = cumulus.MySqlPort, + user = cumulus.MySqlUser + }; + + var monthly = new JsonMysqlSettingsMonthly() + { + table = cumulus.MySqlMonthlyTable + }; - var realtime = new JsonMysqlSettingsRealtime() {enabled = cumulus.RealtimeMySqlEnabled, retention = cumulus.MySqlRealtimeRetention, table = cumulus.MySqlRealtimeTable}; + var realtime = new JsonMysqlSettingsRealtime() + { + retention = cumulus.MySqlRealtimeRetention, + table = cumulus.MySqlRealtimeTable + }; - var dayfile = new JsonMysqlSettingsDayfile() {enabled = cumulus.DayfileMySqlEnabled, table = cumulus.MySqlDayfileTable}; + var dayfile = new JsonMysqlSettingsDayfile() + { + table = cumulus.MySqlDayfileTable + }; var customseconds = new JsonMysqlSettingsCustomSeconds() - { - command = cumulus.CustomMySqlSecondsCommandString, - enabled = cumulus.CustomMySqlSecondsEnabled, - interval = cumulus.CustomMySqlSecondsInterval - }; + { + command = cumulus.CustomMySqlSecondsCommandString, + interval = cumulus.CustomMySqlSecondsInterval + }; var customminutes = new JsonMysqlSettingsCustomMinutes() - { - command = cumulus.CustomMySqlMinutesCommandString, - enabled = cumulus.CustomMySqlMinutesEnabled, - intervalindex = cumulus.CustomMySqlMinutesIntervalIndex - }; + { + command = cumulus.CustomMySqlMinutesCommandString, + intervalindex = cumulus.CustomMySqlMinutesIntervalIndex + }; - var customrollover = new JsonMysqlSettingsCustomRollover() {command = cumulus.CustomMySqlRolloverCommandString, enabled = cumulus.CustomMySqlRolloverEnabled}; + var customrollover = new JsonMysqlSettingsCustomRollover() + { + command = cumulus.CustomMySqlRolloverCommandString, + }; var data = new JsonMysqlSettings() - { - server = server, - monthly = monthly, - realtime = realtime, - dayfile = dayfile, - customseconds = customseconds, - customminutes = customminutes, - customrollover = customrollover - }; + { + server = server, + monthenabled = cumulus.MonthlyMySqlEnabled, + monthly = monthly, + realtimeenabled = cumulus.RealtimeMySqlEnabled, + realtime = realtime, + dayenabled = cumulus.DayfileMySqlEnabled, + dayfile = dayfile, + custsecsenabled = cumulus.CustomMySqlSecondsEnabled, + customseconds = customseconds, + custminsenabled = cumulus.CustomMySqlMinutesEnabled, + customminutes = customminutes, + custrollenabled = cumulus.CustomMySqlRolloverEnabled, + customrollover = customrollover + }; return data.ToJson(); } @@ -114,34 +131,52 @@ public object UpdateMysqlConfig(IHttpContext context) cumulus.MySqlUser = settings.server.user; cumulus.MySqlPass = settings.server.pass; //monthly - cumulus.MonthlyMySqlEnabled = settings.monthly.enabled; - cumulus.MySqlMonthlyTable = String.IsNullOrWhiteSpace(settings.monthly.table) ? "Monthly" : settings.monthly.table; + cumulus.MonthlyMySqlEnabled = settings.monthenabled; + if (cumulus.MonthlyMySqlEnabled) + { + cumulus.MySqlMonthlyTable = String.IsNullOrWhiteSpace(settings.monthly.table) ? "Monthly" : settings.monthly.table; + } //realtime - cumulus.RealtimeMySqlEnabled = settings.realtime.enabled; - cumulus.MySqlRealtimeRetention = settings.realtime.retention; - cumulus.MySqlRealtimeTable = String.IsNullOrWhiteSpace(settings.realtime.table) ? "Realtime" : settings.realtime.table; + cumulus.RealtimeMySqlEnabled = settings.realtimeenabled; + if (cumulus.RealtimeMySqlEnabled) + { + cumulus.MySqlRealtimeRetention = settings.realtime.retention; + cumulus.MySqlRealtimeTable = String.IsNullOrWhiteSpace(settings.realtime.table) ? "Realtime" : settings.realtime.table; + } //dayfile - cumulus.DayfileMySqlEnabled = settings.dayfile.enabled; - cumulus.MySqlDayfileTable = String.IsNullOrWhiteSpace(settings.dayfile.table) ? "Dayfile" : settings.dayfile.table; + cumulus.DayfileMySqlEnabled = settings.dayenabled; + if (cumulus.DayfileMySqlEnabled) + { + cumulus.MySqlDayfileTable = String.IsNullOrWhiteSpace(settings.dayfile.table) ? "Dayfile" : settings.dayfile.table; + } // custom seconds - cumulus.CustomMySqlSecondsCommandString = settings.customseconds.command; - cumulus.CustomMySqlSecondsEnabled = settings.customseconds.enabled; - cumulus.CustomMySqlSecondsInterval = settings.customseconds.interval; - // custom minutes - cumulus.CustomMySqlMinutesCommandString = settings.customminutes.command; - cumulus.CustomMySqlMinutesEnabled = settings.customminutes.enabled; - cumulus.CustomMySqlMinutesIntervalIndex = settings.customminutes.intervalindex; - if (cumulus.CustomMySqlMinutesIntervalIndex >= 0 && cumulus.CustomMySqlMinutesIntervalIndex < cumulus.FactorsOf60.Length) + cumulus.CustomMySqlSecondsEnabled = settings.custsecsenabled; + if (cumulus.CustomMySqlSecondsEnabled) { - cumulus.CustomMySqlMinutesInterval = cumulus.FactorsOf60[cumulus.CustomMySqlMinutesIntervalIndex]; + cumulus.CustomMySqlSecondsCommandString = settings.customseconds.command; + cumulus.CustomMySqlSecondsInterval = settings.customseconds.interval; } - else + // custom minutes + cumulus.CustomMySqlMinutesEnabled = settings.custminsenabled; + if (cumulus.CustomMySqlMinutesEnabled) { - cumulus.CustomMySqlMinutesInterval = 10; + cumulus.CustomMySqlMinutesCommandString = settings.customminutes.command; + cumulus.CustomMySqlMinutesIntervalIndex = settings.customminutes.intervalindex; + if (cumulus.CustomMySqlMinutesIntervalIndex >= 0 && cumulus.CustomMySqlMinutesIntervalIndex < cumulus.FactorsOf60.Length) + { + cumulus.CustomMySqlMinutesInterval = cumulus.FactorsOf60[cumulus.CustomMySqlMinutesIntervalIndex]; + } + else + { + cumulus.CustomMySqlMinutesInterval = 10; + } } // custom rollover - cumulus.CustomMySqlRolloverCommandString = settings.customrollover.command; - cumulus.CustomMySqlRolloverEnabled = settings.customrollover.enabled; + cumulus.CustomMySqlRolloverEnabled = settings.custrollenabled; + if (cumulus.CustomMySqlRolloverEnabled) + { + cumulus.CustomMySqlRolloverCommandString = settings.customrollover.command; + } // Save the settings cumulus.WriteIniFile(); @@ -267,11 +302,17 @@ public string CreateRealtimeSQL(IHttpContext context) public class JsonMysqlSettings { public JsonMysqlSettingsServer server { get; set; } + public bool monthenabled { get; set; } public JsonMysqlSettingsMonthly monthly { get; set; } + public bool realtimeenabled { get; set; } public JsonMysqlSettingsRealtime realtime { get; set; } + public bool dayenabled { get; set; } public JsonMysqlSettingsDayfile dayfile { get; set; } + public bool custsecsenabled { get; set; } public JsonMysqlSettingsCustomSeconds customseconds { get; set; } + public bool custminsenabled { get; set; } public JsonMysqlSettingsCustomMinutes customminutes { get; set; } + public bool custrollenabled { get; set; } public JsonMysqlSettingsCustomRollover customrollover { get; set; } } @@ -286,40 +327,34 @@ public class JsonMysqlSettingsServer public class JsonMysqlSettingsMonthly { - public bool enabled { get; set; } public string table { get; set; } } public class JsonMysqlSettingsRealtime { - public bool enabled { get; set; } public string table { get; set; } public string retention { get; set; } } public class JsonMysqlSettingsDayfile { - public bool enabled { get; set; } public string table { get; set; } } public class JsonMysqlSettingsCustomSeconds { public string command { get; set; } - public bool enabled { get; set; } public int interval { get; set; } } public class JsonMysqlSettingsCustomMinutes { public string command { get; set; } - public bool enabled { get; set; } public int intervalindex { get; set; } } public class JsonMysqlSettingsCustomRollover { public string command { get; set; } - public bool enabled { get; set; } } } diff --git a/CumulusMX/NOAA.cs b/CumulusMX/NOAA.cs index 6b5d4988..df4fee63 100644 --- a/CumulusMX/NOAA.cs +++ b/CumulusMX/NOAA.cs @@ -569,7 +569,7 @@ public List CreateMonthlyReport(DateTime thedate) output.Add($"Elevation: {elev} Lat: {string.Format("{0} {1,2:D2}° {2,2:D2}' {3,2:D2}\"", lathem, latdeg, latmin, latsec)} Lon: {string.Format("{0} {1,3:D3}° {2,2:D2}' {3,2:D2}\"", lonhem, londeg, lonmin, lonsec)}"); output.Add(""); - output.Add($" Temperature ({cumulus.TempUnitText}), Rain ({cumulus.RainUnitText}), Wind Speed ({cumulus.WindUnitText})"); + output.Add($" Temperature ({cumulus.Units.TempText}), Rain ({cumulus.Units.RainText}), Wind Speed ({cumulus.Units.WindText})"); output.Add(""); output.Add(" Heat Cool Avg"); output.Add(" Mean Deg Deg Wind Dom"); @@ -710,7 +710,7 @@ public List CreateMonthlyReport(DateTime thedate) output.Add($"Max Rain: {maxrain.ToString(cumulus.RainFormat, culture)} on day {maxrainday}"); - output.Add($"Days of Rain: {raincount1} (>= {cumulus.NOAAraincomp1.ToString(cumulus.RainFormat, culture)} {cumulus.RainUnitText}) {raincount2} (>= {cumulus.NOAAraincomp2.ToString(cumulus.RainFormat, culture)} {cumulus.RainUnitText}) {raincount3} (>= {cumulus.NOAAraincomp3.ToString(cumulus.RainFormat, culture)} {cumulus.RainUnitText})"); + output.Add($"Days of Rain: {raincount1} (>= {cumulus.NOAAraincomp1.ToString(cumulus.RainFormat, culture)} {cumulus.Units.RainText}) {raincount2} (>= {cumulus.NOAAraincomp2.ToString(cumulus.RainFormat, culture)} {cumulus.Units.RainText}) {raincount3} (>= {cumulus.NOAAraincomp3.ToString(cumulus.RainFormat, culture)} {cumulus.Units.RainText})"); output.Add($"Heat Base: {cumulus.NOAAheatingthreshold.ToString(cumulus.TempFormat, culture)} Cool Base: {cumulus.NOAAcoolingthreshold.ToString(cumulus.TempFormat, culture)} Method: Integration"); return output; @@ -937,7 +937,7 @@ public List CreateYearlyReport(DateTime thedate) output.Add($"Elevation: {elev} Lat: {string.Format("{0} {1,2:D2}° {2,2:D2}' {3,2:D2}\"", lathem, latdeg, latmin, latsec)} Lon: {string.Format("{0} {1,3:D3}° {2,2:D2}' {3,2:D2}\"", lonhem, londeg, lonmin, lonsec)}"); output.Add(""); - output.Add($" Temperature ({cumulus.TempUnitText}), Heat Base: {cumulus.NOAAheatingthreshold.ToString(cumulus.TempFormat, culture)} Cool Base: {cumulus.NOAAcoolingthreshold.ToString(cumulus.TempFormat, culture)}"); + output.Add($" Temperature ({cumulus.Units.TempText}), Heat Base: {cumulus.NOAAheatingthreshold.ToString(cumulus.TempFormat, culture)} Cool Base: {cumulus.NOAAcoolingthreshold.ToString(cumulus.TempFormat, culture)}"); output.Add(" Dep. Heat Cool Max Max Min Min"); output.Add(" Mean Mean From Deg Deg >= <= <= <="); //@ Unsupported function or procedure: 'Format' @@ -1048,7 +1048,7 @@ public List CreateYearlyReport(DateTime thedate) // Rain section header output.Add(""); - output.Add(" Precipitation (" + cumulus.RainUnitText + ")"); + output.Add(" Precipitation (" + cumulus.Units.RainText + ")"); output.Add(""); output.Add(" Dep. Max Days of Rain"); output.Add(" From Obs. >="); @@ -1134,7 +1134,7 @@ public List CreateYearlyReport(DateTime thedate) } output.Add(""); - output.Add($" Wind Speed ({cumulus.WindUnitText})"); + output.Add($" Wind Speed ({cumulus.Units.WindText})"); output.Add(" Dom"); output.Add(" YR MO Avg. Hi Date Dir"); output.Add("------------------------------"); diff --git a/CumulusMX/NOAASettings.cs b/CumulusMX/NOAASettings.cs index a5e6e20b..3ea5ed37 100644 --- a/CumulusMX/NOAASettings.cs +++ b/CumulusMX/NOAASettings.cs @@ -24,62 +24,62 @@ public string GetNoaaAlpacaFormData() { //var InvC = new CultureInfo(""); var normalmeantemps = new JsonNOAASettingsNormalMeanTemps() - { - jan = Math.Round(cumulus.NOAATempNorms[1],cumulus.TempDPlaces), - feb = Math.Round(cumulus.NOAATempNorms[2], cumulus.TempDPlaces), - mar = Math.Round(cumulus.NOAATempNorms[3], cumulus.TempDPlaces), - apr = Math.Round(cumulus.NOAATempNorms[4], cumulus.TempDPlaces), - may = Math.Round(cumulus.NOAATempNorms[5], cumulus.TempDPlaces), - jun = Math.Round(cumulus.NOAATempNorms[6], cumulus.TempDPlaces), - jul = Math.Round(cumulus.NOAATempNorms[7], cumulus.TempDPlaces), - aug = Math.Round(cumulus.NOAATempNorms[8], cumulus.TempDPlaces), - sep = Math.Round(cumulus.NOAATempNorms[9], cumulus.TempDPlaces), - oct = Math.Round(cumulus.NOAATempNorms[10], cumulus.TempDPlaces), - nov = Math.Round(cumulus.NOAATempNorms[11], cumulus.TempDPlaces), - dec = Math.Round(cumulus.NOAATempNorms[12], cumulus.TempDPlaces) - }; + { + jan = Math.Round(cumulus.NOAATempNorms[1],cumulus.TempDPlaces), + feb = Math.Round(cumulus.NOAATempNorms[2], cumulus.TempDPlaces), + mar = Math.Round(cumulus.NOAATempNorms[3], cumulus.TempDPlaces), + apr = Math.Round(cumulus.NOAATempNorms[4], cumulus.TempDPlaces), + may = Math.Round(cumulus.NOAATempNorms[5], cumulus.TempDPlaces), + jun = Math.Round(cumulus.NOAATempNorms[6], cumulus.TempDPlaces), + jul = Math.Round(cumulus.NOAATempNorms[7], cumulus.TempDPlaces), + aug = Math.Round(cumulus.NOAATempNorms[8], cumulus.TempDPlaces), + sep = Math.Round(cumulus.NOAATempNorms[9], cumulus.TempDPlaces), + oct = Math.Round(cumulus.NOAATempNorms[10], cumulus.TempDPlaces), + nov = Math.Round(cumulus.NOAATempNorms[11], cumulus.TempDPlaces), + dec = Math.Round(cumulus.NOAATempNorms[12], cumulus.TempDPlaces) + }; var normalrain = new JsonNOAASettingsNormalRain() - { - jan = Math.Round(cumulus.NOAARainNorms[1], cumulus.RainDPlaces), - feb = Math.Round(cumulus.NOAARainNorms[2], cumulus.RainDPlaces), - mar = Math.Round(cumulus.NOAARainNorms[3], cumulus.RainDPlaces), - apr = Math.Round(cumulus.NOAARainNorms[4], cumulus.RainDPlaces), - may = Math.Round(cumulus.NOAARainNorms[5], cumulus.RainDPlaces), - jun = Math.Round(cumulus.NOAARainNorms[6], cumulus.RainDPlaces), - jul = Math.Round(cumulus.NOAARainNorms[7], cumulus.RainDPlaces), - aug = Math.Round(cumulus.NOAARainNorms[8], cumulus.RainDPlaces), - sep = Math.Round(cumulus.NOAARainNorms[9], cumulus.RainDPlaces), - oct = Math.Round(cumulus.NOAARainNorms[10], cumulus.RainDPlaces), - nov = Math.Round(cumulus.NOAARainNorms[11], cumulus.RainDPlaces), - dec = Math.Round(cumulus.NOAARainNorms[12], cumulus.RainDPlaces) - }; + { + jan = Math.Round(cumulus.NOAARainNorms[1], cumulus.RainDPlaces), + feb = Math.Round(cumulus.NOAARainNorms[2], cumulus.RainDPlaces), + mar = Math.Round(cumulus.NOAARainNorms[3], cumulus.RainDPlaces), + apr = Math.Round(cumulus.NOAARainNorms[4], cumulus.RainDPlaces), + may = Math.Round(cumulus.NOAARainNorms[5], cumulus.RainDPlaces), + jun = Math.Round(cumulus.NOAARainNorms[6], cumulus.RainDPlaces), + jul = Math.Round(cumulus.NOAARainNorms[7], cumulus.RainDPlaces), + aug = Math.Round(cumulus.NOAARainNorms[8], cumulus.RainDPlaces), + sep = Math.Round(cumulus.NOAARainNorms[9], cumulus.RainDPlaces), + oct = Math.Round(cumulus.NOAARainNorms[10], cumulus.RainDPlaces), + nov = Math.Round(cumulus.NOAARainNorms[11], cumulus.RainDPlaces), + dec = Math.Round(cumulus.NOAARainNorms[12], cumulus.RainDPlaces) + }; var data = new JsonNOAASettingsData() - { - sitename = cumulus.NOAAname, - city = cumulus.NOAAcity, - state = cumulus.NOAAstate, - timeformat = cumulus.NOAA12hourformat?0:1, - monthfileformat = cumulus.NOAAMonthFileFormat, - yearfileformat = cumulus.NOAAYearFileFormat, - utf8 = cumulus.NOAAUseUTF8, - dotdecimal = cumulus.NOAAUseDotDecimal, - autosave = cumulus.NOAAAutoSave, - autoftp = cumulus.NOAAAutoFTP, - ftpdirectory = cumulus.NOAAFTPDirectory, - heatingthreshold = Math.Round(cumulus.NOAAheatingthreshold,cumulus.TempDPlaces), - coolingthreshold = Math.Round(cumulus.NOAAcoolingthreshold,cumulus.TempDPlaces), - maxtempcomp1 = Math.Round(cumulus.NOAAmaxtempcomp1,cumulus.RainDPlaces), - maxtempcomp2 = Math.Round(cumulus.NOAAmaxtempcomp2,cumulus.RainDPlaces), - mintempcomp1 = Math.Round(cumulus.NOAAmintempcomp1,cumulus.RainDPlaces), - mintempcomp2 = Math.Round(cumulus.NOAAmintempcomp2,cumulus.RainDPlaces), - raincomp1 = Math.Round(cumulus.NOAAraincomp1,cumulus.RainDPlaces), - raincomp2 = Math.Round(cumulus.NOAAraincomp2,cumulus.RainDPlaces), - raincomp3 = Math.Round(cumulus.NOAAraincomp3, cumulus.RainDPlaces), - normalmeantemps = normalmeantemps, - normalrain = normalrain - }; + { + sitename = cumulus.NOAAname, + city = cumulus.NOAAcity, + state = cumulus.NOAAstate, + timeformat = cumulus.NOAA12hourformat?0:1, + monthfileformat = cumulus.NOAAMonthFileFormat, + yearfileformat = cumulus.NOAAYearFileFormat, + utf8 = cumulus.NOAAUseUTF8, + dotdecimal = cumulus.NOAAUseDotDecimal, + autosave = cumulus.NOAAAutoSave, + autoftp = cumulus.NOAAAutoFTP, + ftpdirectory = cumulus.NOAAFTPDirectory, + heatingthreshold = Math.Round(cumulus.NOAAheatingthreshold,cumulus.TempDPlaces), + coolingthreshold = Math.Round(cumulus.NOAAcoolingthreshold,cumulus.TempDPlaces), + maxtempcomp1 = Math.Round(cumulus.NOAAmaxtempcomp1,cumulus.RainDPlaces), + maxtempcomp2 = Math.Round(cumulus.NOAAmaxtempcomp2,cumulus.RainDPlaces), + mintempcomp1 = Math.Round(cumulus.NOAAmintempcomp1,cumulus.RainDPlaces), + mintempcomp2 = Math.Round(cumulus.NOAAmintempcomp2,cumulus.RainDPlaces), + raincomp1 = Math.Round(cumulus.NOAAraincomp1,cumulus.RainDPlaces), + raincomp2 = Math.Round(cumulus.NOAAraincomp2,cumulus.RainDPlaces), + raincomp3 = Math.Round(cumulus.NOAAraincomp3, cumulus.RainDPlaces), + normalmeantemps = normalmeantemps, + normalrain = normalrain + }; return data.ToJson(); } @@ -117,54 +117,57 @@ public string UpdateNoaaConfig(IHttpContext context) // process the settings cumulus.LogMessage("Updating NOAA settings"); - cumulus.NOAAname = settings.sitename; - cumulus.NOAAcity = settings.city; - cumulus.NOAAstate = settings.state; - cumulus.NOAA12hourformat = settings.timeformat == 0; - cumulus.NOAAMonthFileFormat = settings.monthfileformat; - cumulus.NOAAYearFileFormat = settings.yearfileformat; - cumulus.NOAAUseUTF8 = settings.utf8; - cumulus.NOAAUseDotDecimal = settings.dotdecimal; cumulus.NOAAAutoSave = settings.autosave; - cumulus.NOAAAutoFTP = settings.autoftp; - cumulus.NOAAFTPDirectory = settings.ftpdirectory; - cumulus.NOAAheatingthreshold = settings.heatingthreshold; - cumulus.NOAAcoolingthreshold = settings.coolingthreshold; - cumulus.NOAAmaxtempcomp1 = settings.maxtempcomp1; - cumulus.NOAAmaxtempcomp2 = settings.maxtempcomp2; - cumulus.NOAAmintempcomp1 = settings.mintempcomp1; - cumulus.NOAAmintempcomp2 = settings.mintempcomp2; - cumulus.NOAAraincomp1 = settings.raincomp1; - cumulus.NOAAraincomp2 = settings.raincomp2; - cumulus.NOAAraincomp3 = settings.raincomp3; - - // normal mean temps - cumulus.NOAATempNorms[1] = settings.normalmeantemps.jan; - cumulus.NOAATempNorms[2] = settings.normalmeantemps.feb; - cumulus.NOAATempNorms[3] = settings.normalmeantemps.mar; - cumulus.NOAATempNorms[4] = settings.normalmeantemps.apr; - cumulus.NOAATempNorms[5] = settings.normalmeantemps.may; - cumulus.NOAATempNorms[6] = settings.normalmeantemps.jun; - cumulus.NOAATempNorms[7] = settings.normalmeantemps.jul; - cumulus.NOAATempNorms[8] = settings.normalmeantemps.aug; - cumulus.NOAATempNorms[9] = settings.normalmeantemps.sep; - cumulus.NOAATempNorms[10] = settings.normalmeantemps.oct; - cumulus.NOAATempNorms[11] = settings.normalmeantemps.nov; - cumulus.NOAATempNorms[12] = settings.normalmeantemps.dec; - - // normal rain - cumulus.NOAARainNorms[1] = settings.normalrain.jan; - cumulus.NOAARainNorms[2] = settings.normalrain.feb; - cumulus.NOAARainNorms[3] = settings.normalrain.mar; - cumulus.NOAARainNorms[4] = settings.normalrain.apr; - cumulus.NOAARainNorms[5] = settings.normalrain.may; - cumulus.NOAARainNorms[6] = settings.normalrain.jun; - cumulus.NOAARainNorms[6] = settings.normalrain.jul; - cumulus.NOAARainNorms[8] = settings.normalrain.aug; - cumulus.NOAARainNorms[9] = settings.normalrain.sep; - cumulus.NOAARainNorms[10] = settings.normalrain.oct; - cumulus.NOAARainNorms[11] = settings.normalrain.nov; - cumulus.NOAARainNorms[12] = settings.normalrain.dec; + if (cumulus.NOAAAutoSave) + { + cumulus.NOAAname = settings.sitename; + cumulus.NOAAcity = settings.city; + cumulus.NOAAstate = settings.state; + cumulus.NOAA12hourformat = settings.timeformat == 0; + cumulus.NOAAMonthFileFormat = settings.monthfileformat; + cumulus.NOAAYearFileFormat = settings.yearfileformat; + cumulus.NOAAUseUTF8 = settings.utf8; + cumulus.NOAAUseDotDecimal = settings.dotdecimal; + cumulus.NOAAAutoFTP = settings.autoftp; + cumulus.NOAAFTPDirectory = settings.ftpdirectory; + cumulus.NOAAheatingthreshold = settings.heatingthreshold; + cumulus.NOAAcoolingthreshold = settings.coolingthreshold; + cumulus.NOAAmaxtempcomp1 = settings.maxtempcomp1; + cumulus.NOAAmaxtempcomp2 = settings.maxtempcomp2; + cumulus.NOAAmintempcomp1 = settings.mintempcomp1; + cumulus.NOAAmintempcomp2 = settings.mintempcomp2; + cumulus.NOAAraincomp1 = settings.raincomp1; + cumulus.NOAAraincomp2 = settings.raincomp2; + cumulus.NOAAraincomp3 = settings.raincomp3; + + // normal mean temps + cumulus.NOAATempNorms[1] = settings.normalmeantemps.jan; + cumulus.NOAATempNorms[2] = settings.normalmeantemps.feb; + cumulus.NOAATempNorms[3] = settings.normalmeantemps.mar; + cumulus.NOAATempNorms[4] = settings.normalmeantemps.apr; + cumulus.NOAATempNorms[5] = settings.normalmeantemps.may; + cumulus.NOAATempNorms[6] = settings.normalmeantemps.jun; + cumulus.NOAATempNorms[7] = settings.normalmeantemps.jul; + cumulus.NOAATempNorms[8] = settings.normalmeantemps.aug; + cumulus.NOAATempNorms[9] = settings.normalmeantemps.sep; + cumulus.NOAATempNorms[10] = settings.normalmeantemps.oct; + cumulus.NOAATempNorms[11] = settings.normalmeantemps.nov; + cumulus.NOAATempNorms[12] = settings.normalmeantemps.dec; + + // normal rain + cumulus.NOAARainNorms[1] = settings.normalrain.jan; + cumulus.NOAARainNorms[2] = settings.normalrain.feb; + cumulus.NOAARainNorms[3] = settings.normalrain.mar; + cumulus.NOAARainNorms[4] = settings.normalrain.apr; + cumulus.NOAARainNorms[5] = settings.normalrain.may; + cumulus.NOAARainNorms[6] = settings.normalrain.jun; + cumulus.NOAARainNorms[6] = settings.normalrain.jul; + cumulus.NOAARainNorms[8] = settings.normalrain.aug; + cumulus.NOAARainNorms[9] = settings.normalrain.sep; + cumulus.NOAARainNorms[10] = settings.normalrain.oct; + cumulus.NOAARainNorms[11] = settings.normalrain.nov; + cumulus.NOAARainNorms[12] = settings.normalrain.dec; + } // Save the settings cumulus.WriteIniFile(); diff --git a/CumulusMX/Program.cs b/CumulusMX/Program.cs index 7af8e47b..98897bea 100644 --- a/CumulusMX/Program.cs +++ b/CumulusMX/Program.cs @@ -315,6 +315,11 @@ private static bool Handler(CtrlType sig) Program.cumulus.LogConsoleMessage("Cumulus terminating"); Program.cumulus.Stop(); } + else + { + Trace.WriteLine("Cumulus has not finished initialising, a clean exit is not possible, forcing exit"); + Environment.Exit(2); + } Trace.WriteLine("Cumulus has shutdown"); Console.WriteLine("Cumulus stopped"); diff --git a/CumulusMX/ProgramSettings.cs b/CumulusMX/ProgramSettings.cs index 17cac726..a46349b9 100644 --- a/CumulusMX/ProgramSettings.cs +++ b/CumulusMX/ProgramSettings.cs @@ -23,20 +23,29 @@ public ProgramSettings(Cumulus cumulus) public string GetProgramAlpacaFormData() { // Build the settings data, convert to JSON, and return it - var options = new JsonProgramSettingsOptions() + var startup = new JsonProgramSettingsStartupOptions() { startuphostping = cumulus.ProgramOptions.StartupPingHost, startuppingescape = cumulus.ProgramOptions.StartupPingEscapeTime, startupdelay = cumulus.ProgramOptions.StartupDelaySecs, - startupdelaymaxuptime = cumulus.ProgramOptions.StartupDelayMaxUptime, + startupdelaymaxuptime = cumulus.ProgramOptions.StartupDelayMaxUptime + }; + + var options = new JsonProgramSettingsGeneralOptions() + { debuglogging = cumulus.ProgramOptions.DebugLogging, datalogging = cumulus.ProgramOptions.DataLogging, stopsecondinstance = cumulus.ProgramOptions.WarnMultiple }; + var settings = new JsonProgramSettings() + { + startup = startup, + options = options + }; //return JsonConvert.SerializeObject(data); - return JsonSerializer.SerializeToString(options); + return JsonSerializer.SerializeToString(settings); } public string GetProgramAlpacaFormOptions() @@ -73,18 +82,18 @@ public string UpdateProgramConfig(IHttpContext context) var json = WebUtility.UrlDecode(data.Substring(5)); // de-serialize it to the settings structure - var settings = JsonSerializer.DeserializeFromString(json); + var settings = JsonSerializer.DeserializeFromString(json); // process the settings try { - cumulus.ProgramOptions.StartupPingHost = settings.startuphostping; - cumulus.ProgramOptions.StartupPingEscapeTime = settings.startuppingescape; - cumulus.ProgramOptions.StartupDelaySecs = settings.startupdelay; - cumulus.ProgramOptions.StartupDelayMaxUptime = settings.startupdelaymaxuptime; - cumulus.ProgramOptions.DebugLogging = settings.debuglogging; - cumulus.ProgramOptions.DataLogging = settings.datalogging; - cumulus.ProgramOptions.WarnMultiple = settings.stopsecondinstance; + cumulus.ProgramOptions.StartupPingHost = settings.startup.startuphostping; + cumulus.ProgramOptions.StartupPingEscapeTime = settings.startup.startuppingescape; + cumulus.ProgramOptions.StartupDelaySecs = settings.startup.startupdelay; + cumulus.ProgramOptions.StartupDelayMaxUptime = settings.startup.startupdelaymaxuptime; + cumulus.ProgramOptions.DebugLogging = settings.options.debuglogging; + cumulus.ProgramOptions.DataLogging = settings.options.datalogging; + cumulus.ProgramOptions.WarnMultiple = settings.options.stopsecondinstance; } catch (Exception ex) { @@ -108,12 +117,22 @@ public string UpdateProgramConfig(IHttpContext context) } } - public class JsonProgramSettingsOptions + public class JsonProgramSettings + { + public JsonProgramSettingsStartupOptions startup { get; set; } + public JsonProgramSettingsGeneralOptions options { get; set; } + } + + public class JsonProgramSettingsStartupOptions { public string startuphostping { get; set; } public int startuppingescape { get; set; } public int startupdelay { get; set; } public int startupdelaymaxuptime { get; set; } + } + + public class JsonProgramSettingsGeneralOptions + { public bool debuglogging { get; set; } public bool datalogging { get; set; } public bool stopsecondinstance { get; set; } diff --git a/CumulusMX/Properties/AssemblyInfo.cs b/CumulusMX/Properties/AssemblyInfo.cs index 3e964b74..f03aa2bc 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("Build 3107")] +[assembly: AssemblyDescription("Build 3108")] [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.9.7.3107")] -[assembly: AssemblyFileVersion("3.9.7.3107")] +[assembly: AssemblyVersion("3.10.0.3108")] +[assembly: AssemblyFileVersion("3.10.0.3108")] diff --git a/CumulusMX/StationSettings.cs b/CumulusMX/StationSettings.cs index 1a7e329a..9c3d8d2b 100644 --- a/CumulusMX/StationSettings.cs +++ b/CumulusMX/StationSettings.cs @@ -27,6 +27,13 @@ internal StationSettings(Cumulus cumulus, WeatherStation station) internal string GetStationAlpacaFormData() { // Build the settings data, convert to JSON, and return it + var optionsAdv = new JsonStationSettingsOptionsAdvanced() + { + avgbearingmins = cumulus.StationOptions.AvgBearingMinutes, + avgspeedmins = cumulus.StationOptions.AvgSpeedMinutes, + peakgustmins = cumulus.StationOptions.PeakGustMinutes + }; + var options = new JsonStationSettingsOptions() { usezerobearing = cumulus.StationOptions.UseZeroBearing, @@ -36,31 +43,76 @@ internal string GetStationAlpacaFormData() calculatedewpoint = cumulus.StationOptions.CalculatedDP, calculatewindchill = cumulus.StationOptions.CalculatedWC, syncstationclock = cumulus.StationOptions.SyncTime, + syncclockhour = cumulus.StationOptions.ClockSettingHour, cumuluspresstrendnames = cumulus.StationOptions.UseCumulusPresstrendstr, - vp1minbarupdate = cumulus.StationOptions.ForceVPBarUpdate, extrasensors = cumulus.StationOptions.LogExtraSensors, ignorelacrosseclock = cumulus.StationOptions.WS2300IgnoreStationClock, roundwindspeeds = cumulus.StationOptions.RoundWindSpeed, - synchroniseforeads = cumulus.StationOptions.SyncFOReads, - readreceptionstats = cumulus.StationOptions.DavisReadReceptionStats + nosensorcheck = cumulus.StationOptions.NoSensorCheck, + advanced = optionsAdv + }; + + var unitsAdv = new JsonStationSettingsUnitsAdvanced + { + airqulaitydp = cumulus.AirQualityDPlaces, + pressdp = cumulus.PressDPlaces, + raindp = cumulus.RainDPlaces, + sunshinedp = cumulus.SunshineDPlaces, + tempdp = cumulus.TempDPlaces, + uvdp = cumulus.UVDPlaces, + windavgdp = cumulus.WindAvgDPlaces, + winddp = cumulus.WindDPlaces, + windrundp = cumulus.WindRunDPlaces }; var units = new JsonStationSettingsUnits() { - wind = cumulus.WindUnit, - pressure = cumulus.PressUnit, + wind = cumulus.Units.Wind, + pressure = cumulus.Units.Press, temp = cumulus.TempUnit, - rain = cumulus.RainUnit + rain = cumulus.RainUnit, + advanced = unitsAdv }; var tcpsettings = new JsonStationSettingsTCPsettings() { - ipaddress = cumulus.VP2IPAddr, - tcpport = cumulus.VP2TCPPort, - disconperiod = cumulus.VP2PeriodicDisconnectInterval + ipaddress = cumulus.DavisOptions.IPAddr, + tcpport = cumulus.DavisOptions.TCPPort, + disconperiod = cumulus.DavisOptions.PeriodicDisconnectInterval + }; + + var davisconn = new JsonStationSettingsDavisConn() + { + conntype = cumulus.DavisOptions.ConnectionType, + tcpsettings = tcpsettings + }; + + var davisCommonAdvanced = new JsonStationSettingsDavisCommonAdvanced() + { + raingaugetype = cumulus.DavisOptions.RainGaugeType }; - var davisconn = new JsonStationSettingsDavisConn() {conntype = cumulus.VP2ConnectionType, tcpsettings = tcpsettings}; + var davisCommon = new JsonStationSettingsDavisCommon() + { + davisconn = davisconn, + advanced = davisCommonAdvanced + }; + + var davisvp2advanced = new JsonStationSettingsDavisVp2Advanced() + { + useloop2 = cumulus.DavisOptions.UseLoop2, + vp1minbarupdate = cumulus.DavisOptions.ForceVPBarUpdate, + initwaittime = cumulus.DavisOptions.InitWaitTime, + ipresponsetime = cumulus.DavisOptions.IPResponseTime, + baudrate = cumulus.DavisOptions.BaudRate + }; + + var davisvp2 = new JsonStationSettingsDavisVp2() + { + readreceptionstats = cumulus.DavisOptions.ReadReceptionStats, + setloggerinterval = cumulus.DavisOptions.SetLoggerInterval, + advanced = davisvp2advanced + }; var gw1000 = new JSonStationSettingsGw1000Conn() {ipaddress = cumulus.Gw1000IpAddress, autoDiscover = cumulus.Gw1000AutoUpdateIpAddress, macaddress = cumulus.Gw1000MacAddress }; @@ -71,6 +123,37 @@ internal string GetStationAlpacaFormData() logrollover.time = "9am"; } + var fineoffset = new JsonStationSettingsFineOffset() + { + syncreads = cumulus.FineOffsetOptions.FineOffsetSyncReads, + readtime = cumulus.FineOffsetOptions.FineOffsetReadTime, + readavoid = cumulus.FineOffsetOptions.FineOffsetReadAvoidPeriod + }; + + var easyweather = new JsonStationSettingsEasyWeather() + { + interval = cumulus.EwOptions.Interval, + filename = cumulus.EwOptions.Filename, + minpressmb = cumulus.EwOptions.MinPressMB, + maxpressmb = cumulus.EwOptions.MaxPressMB, + raintipdiff = cumulus.EwOptions.MaxRainTipDiff, + pressoffset = cumulus.EwOptions.PressOffset + }; + + var imetAdvanced = new JsonStationSettingsImetAdvanced() + { + readdelay = cumulus.ImetOptions.ImetReadDelay, + waittime = cumulus.ImetOptions.ImetWaitTime, + updatelogpointer = cumulus.ImetOptions.ImetUpdateLogPointer + }; + + var imet = new JsonStationSettingsImet() + { + baudrate = cumulus.ImetOptions.ImetBaudRate, + advanced = imetAdvanced + }; + + int deg, min, sec; string hem; @@ -122,10 +205,8 @@ internal string GetStationAlpacaFormData() var annualrainfall = new JsonStationSettingsAnnualRainfall() {rainseasonstart = cumulus.RainSeasonStart, ytdamount = cumulus.YTDrain, ytdyear = cumulus.YTDrainyear}; - var graphs = new JsonStationSettingsGraphs() + var graphDataTemp = new JsonStationSettingsGraphDataTemperature() { - graphdays = cumulus.GraphDays, - graphhours = cumulus.GraphHours, graphTempVis = cumulus.GraphOptions.TempVisible, graphInTempVis = cumulus.GraphOptions.InTempVisible, graphHeatIndexVis = cumulus.GraphOptions.HIVisible, @@ -133,14 +214,36 @@ internal string GetStationAlpacaFormData() graphWindChillVis = cumulus.GraphOptions.WCVisible, graphAppTempVis = cumulus.GraphOptions.AppTempVisible, graphFeelsLikeVis = cumulus.GraphOptions.FeelsLikeVisible, - graphHumidexVis = cumulus.GraphOptions.HumidexVisible, + graphHumidexVis = cumulus.GraphOptions.HumidexVisible + }; + + var graphDataHum = new JsonStationSettingsGraphDataHumidity() + { graphHumVis = cumulus.GraphOptions.OutHumVisible, - graphInHumVis = cumulus.GraphOptions.InHumVisible, + graphInHumVis = cumulus.GraphOptions.InHumVisible + }; + + var graphDataSolar = new JsonStationSettingsGraphDataSolar() + { graphUvVis = cumulus.GraphOptions.UVVisible, graphSolarVis = cumulus.GraphOptions.SolarVisible, graphSunshineVis = cumulus.GraphOptions.SunshineVisible }; + var graphDataVis = new JsonStationSettingsGraphVisibility() + { + temperature = graphDataTemp, + humidity = graphDataHum, + solar = graphDataSolar + }; + + var graphs = new JsonStationSettingsGraphs() + { + graphdays = cumulus.GraphDays, + graphhours = cumulus.GraphHours, + datavisibility = graphDataVis + }; + var wllNetwork = new JsonStationSettingsWLLNetwork() { autoDiscover = cumulus.WLLAutoUpdateIpAddress @@ -221,17 +324,27 @@ internal string GetStationAlpacaFormData() extraTemp = wllExtraTemp }; - var data = new JsonStationSettingsData() + var general = new JsonStationGeneral() { stationtype = cumulus.StationType, - units = units, - davisconn = davisconn, - daviswll = wll, - gw1000 = gw1000, comportname = cumulus.ComportName, loginterval = cumulus.DataLogInterval, logrollover = logrollover, - Location = location, + units = units, + Location = location + }; + + var data = new JsonStationSettingsData() + { + stationid = cumulus.StationType, + general = general, + daviscommon = davisCommon, + davisvp2 = davisvp2, + daviswll = wll, + gw1000 = gw1000, + fineoffset = fineoffset, + easyw = easyweather, + imet = imet, Options = options, Forecast = forecast, Solar = solar, @@ -332,19 +445,19 @@ internal string UpdateStationConfig(IHttpContext context) { cumulus.GraphHours = settings.Graphs.graphhours; cumulus.GraphDays = settings.Graphs.graphdays; - cumulus.GraphOptions.TempVisible = settings.Graphs.graphTempVis; - cumulus.GraphOptions.InTempVisible = settings.Graphs.graphInTempVis; - cumulus.GraphOptions.HIVisible = settings.Graphs.graphHeatIndexVis; - cumulus.GraphOptions.DPVisible = settings.Graphs.graphDewPointVis; - cumulus.GraphOptions.WCVisible = settings.Graphs.graphWindChillVis; - cumulus.GraphOptions.AppTempVisible = settings.Graphs.graphAppTempVis; - cumulus.GraphOptions.FeelsLikeVisible = settings.Graphs.graphFeelsLikeVis; - cumulus.GraphOptions.HumidexVisible = settings.Graphs.graphHumidexVis; - cumulus.GraphOptions.OutHumVisible = settings.Graphs.graphHumVis; - cumulus.GraphOptions.InHumVisible = settings.Graphs.graphInHumVis; - cumulus.GraphOptions.UVVisible = settings.Graphs.graphUvVis; - cumulus.GraphOptions.SolarVisible = settings.Graphs.graphSolarVis; - cumulus.GraphOptions.SunshineVisible = settings.Graphs.graphSunshineVis; + cumulus.GraphOptions.TempVisible = settings.Graphs.datavisibility.temperature.graphTempVis; + cumulus.GraphOptions.InTempVisible = settings.Graphs.datavisibility.temperature.graphInTempVis; + cumulus.GraphOptions.HIVisible = settings.Graphs.datavisibility.temperature.graphHeatIndexVis; + cumulus.GraphOptions.DPVisible = settings.Graphs.datavisibility.temperature.graphDewPointVis; + cumulus.GraphOptions.WCVisible = settings.Graphs.datavisibility.temperature.graphWindChillVis; + cumulus.GraphOptions.AppTempVisible = settings.Graphs.datavisibility.temperature.graphAppTempVis; + cumulus.GraphOptions.FeelsLikeVisible = settings.Graphs.datavisibility.temperature.graphFeelsLikeVis; + cumulus.GraphOptions.HumidexVisible = settings.Graphs.datavisibility.temperature.graphHumidexVis; + cumulus.GraphOptions.OutHumVisible = settings.Graphs.datavisibility.humidity.graphHumVis; + cumulus.GraphOptions.InHumVisible = settings.Graphs.datavisibility.humidity.graphInHumVis; + cumulus.GraphOptions.UVVisible = settings.Graphs.datavisibility.solar.graphUvVis; + cumulus.GraphOptions.SolarVisible = settings.Graphs.datavisibility.solar.graphSolarVis; + cumulus.GraphOptions.SunshineVisible = settings.Graphs.datavisibility.solar.graphSunshineVis; } catch (Exception ex) { @@ -372,11 +485,16 @@ internal string UpdateStationConfig(IHttpContext context) // Solar try { - cumulus.SolarMinimum = settings.Solar.solarmin; - cumulus.RStransfactor = settings.Solar.transfactor; - cumulus.SunThreshold = settings.Solar.sunthreshold; - cumulus.SolarCalc = settings.Solar.solarcalc; - cumulus.BrasTurbidity = settings.Solar.turbidity; + if (settings.Solar != null) + { + cumulus.SolarCalc = settings.Solar.solarcalc; + cumulus.SolarMinimum = settings.Solar.solarmin; + cumulus.SunThreshold = settings.Solar.sunthreshold; + if (cumulus.SolarCalc == 0) + cumulus.RStransfactor = settings.Solar.transfactor; + else + cumulus.BrasTurbidity = settings.Solar.turbidity; + } } catch (Exception ex) { @@ -389,11 +507,14 @@ internal string UpdateStationConfig(IHttpContext context) // Forecast try { - cumulus.FChighpress = settings.Forecast.highpressureextreme; - cumulus.FClowpress = settings.Forecast.lowpressureextreme; - cumulus.HourlyForecast = settings.Forecast.updatehourly; cumulus.UseCumulusForecast = settings.Forecast.usecumulusforecast; - cumulus.FCpressinMB = (settings.Forecast.pressureunit == "mb/hPa"); + if (cumulus.UseCumulusForecast) + { + cumulus.FChighpress = settings.Forecast.highpressureextreme; + cumulus.FClowpress = settings.Forecast.lowpressureextreme; + cumulus.HourlyForecast = settings.Forecast.updatehourly; + cumulus.FCpressinMB = (settings.Forecast.pressureunit == "mb/hPa"); + } } catch (Exception ex) { @@ -406,28 +527,28 @@ internal string UpdateStationConfig(IHttpContext context) // Location try { - cumulus.Altitude = settings.Location.altitude; - cumulus.AltitudeInFeet = (settings.Location.altitudeunit == "feet"); - cumulus.LocationName = settings.Location.sitename ?? string.Empty; - cumulus.LocationDesc = settings.Location.description ?? string.Empty; + cumulus.Altitude = settings.general.Location.altitude; + cumulus.AltitudeInFeet = (settings.general.Location.altitudeunit == "feet"); + cumulus.LocationName = settings.general.Location.sitename ?? string.Empty; + cumulus.LocationDesc = settings.general.Location.description ?? string.Empty; - cumulus.Latitude = settings.Location.Latitude.degrees + (settings.Location.Latitude.minutes / 60.0) + (settings.Location.Latitude.seconds / 3600.0); - if (settings.Location.Latitude.hemisphere == "South") + cumulus.Latitude = 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; } - cumulus.LatTxt = string.Format("{0} {1:D2}° {2:D2}' {3:D2}"", settings.Location.Latitude.hemisphere[0], settings.Location.Latitude.degrees, settings.Location.Latitude.minutes, - settings.Location.Latitude.seconds); + 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.Location.Longitude.degrees + (settings.Location.Longitude.minutes / 60.0) + (settings.Location.Longitude.seconds / 3600.0); - if (settings.Location.Longitude.hemisphere == "West") + cumulus.Longitude = 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; } - cumulus.LonTxt = string.Format("{0} {1:D2}° {2:D2}' {3:D2}"", settings.Location.Longitude.hemisphere[0], settings.Location.Longitude.degrees, settings.Location.Longitude.minutes, - settings.Location.Longitude.seconds); + cumulus.LonTxt = string.Format("{0} {1:D2}° {2:D2}' {3:D2}"", settings.general.Location.Longitude.hemisphere[0], settings.general.Location.Longitude.degrees, settings.general.Location.Longitude.minutes, + settings.general.Location.Longitude.seconds); } catch (Exception ex) { @@ -447,13 +568,16 @@ internal string UpdateStationConfig(IHttpContext context) cumulus.StationOptions.CalculatedDP = settings.Options.calculatedewpoint; cumulus.StationOptions.CalculatedWC = settings.Options.calculatewindchill; cumulus.StationOptions.SyncTime = settings.Options.syncstationclock; + cumulus.StationOptions.ClockSettingHour = settings.Options.syncclockhour; cumulus.StationOptions.UseCumulusPresstrendstr = settings.Options.cumuluspresstrendnames; - cumulus.StationOptions.ForceVPBarUpdate = settings.Options.vp1minbarupdate; cumulus.StationOptions.LogExtraSensors = settings.Options.extrasensors; cumulus.StationOptions.WS2300IgnoreStationClock = settings.Options.ignorelacrosseclock; cumulus.StationOptions.RoundWindSpeed = settings.Options.roundwindspeeds; - cumulus.StationOptions.SyncFOReads = settings.Options.synchroniseforeads; - cumulus.StationOptions.DavisReadReceptionStats = settings.Options.readreceptionstats; + cumulus.StationOptions.NoSensorCheck = settings.Options.nosensorcheck; + + cumulus.StationOptions.AvgBearingMinutes = settings.Options.advanced.avgbearingmins; + cumulus.StationOptions.AvgSpeedMinutes = settings.Options.advanced.avgspeedmins; + cumulus.StationOptions.PeakGustMinutes = settings.Options.advanced.peakgustmins; } catch (Exception ex) { @@ -466,9 +590,9 @@ internal string UpdateStationConfig(IHttpContext context) // Log rollover try { - cumulus.RolloverHour = settings.logrollover.time == "9am" ? 9 : 0; - - cumulus.Use10amInSummer = settings.logrollover.summer10am; + cumulus.RolloverHour = settings.general.logrollover.time == "9am" ? 9 : 0; + if (cumulus.RolloverHour == 9) + cumulus.Use10amInSummer = settings.general.logrollover.summer10am; } catch (Exception ex) { @@ -478,60 +602,85 @@ internal string UpdateStationConfig(IHttpContext context) context.Response.StatusCode = 500; } + // Davis VP/VP2/Vue + try + { + if (settings.davisvp2 != null) + { + cumulus.DavisOptions.ReadReceptionStats = settings.davisvp2.readreceptionstats; + cumulus.DavisOptions.SetLoggerInterval = settings.davisvp2.setloggerinterval; + cumulus.DavisOptions.UseLoop2 = settings.davisvp2.advanced.useloop2; + cumulus.DavisOptions.ForceVPBarUpdate = settings.davisvp2.advanced.vp1minbarupdate; + cumulus.DavisOptions.InitWaitTime = settings.davisvp2.advanced.initwaittime; + cumulus.DavisOptions.IPResponseTime = settings.davisvp2.advanced.ipresponsetime; + cumulus.DavisOptions.BaudRate = settings.davisvp2.advanced.baudrate; + } + } + catch (Exception ex) + { + var msg = "Error processing Davis VP/VP2/Vue settings: " + ex.Message; + cumulus.LogMessage(msg); + errorMsg += msg + "\n\n"; + context.Response.StatusCode = 500; + } + // WLL try { - cumulus.WLLAutoUpdateIpAddress = settings.daviswll.network.autoDiscover; - cumulus.WllApiKey = settings.daviswll.api.apiKey; - cumulus.WllApiSecret = settings.daviswll.api.apiSecret; - cumulus.WllStationId = settings.daviswll.api.apiStationId; - - cumulus.WllPrimaryRain = settings.daviswll.primary.rain; - cumulus.WllPrimarySolar = settings.daviswll.primary.solar; - cumulus.WllPrimaryTempHum = settings.daviswll.primary.temphum; - cumulus.WllPrimaryUV = settings.daviswll.primary.uv; - cumulus.WllPrimaryWind = settings.daviswll.primary.wind; - - cumulus.WllExtraLeafTx1 = settings.daviswll.soilLeaf.extraLeaf.leafTx1; - cumulus.WllExtraLeafTx2 = settings.daviswll.soilLeaf.extraLeaf.leafTx2; - cumulus.WllExtraLeafIdx1 = settings.daviswll.soilLeaf.extraLeaf.leafIdx1; - cumulus.WllExtraLeafIdx2 = settings.daviswll.soilLeaf.extraLeaf.leafIdx2; - - cumulus.WllExtraSoilMoistureIdx1 = settings.daviswll.soilLeaf.extraSoilMoist.soilMoistIdx1; - cumulus.WllExtraSoilMoistureIdx2 = settings.daviswll.soilLeaf.extraSoilMoist.soilMoistIdx2; - cumulus.WllExtraSoilMoistureIdx3 = settings.daviswll.soilLeaf.extraSoilMoist.soilMoistIdx3; - cumulus.WllExtraSoilMoistureIdx4 = settings.daviswll.soilLeaf.extraSoilMoist.soilMoistIdx4; - cumulus.WllExtraSoilMoistureTx1 = settings.daviswll.soilLeaf.extraSoilMoist.soilMoistTx1; - cumulus.WllExtraSoilMoistureTx2 = settings.daviswll.soilLeaf.extraSoilMoist.soilMoistTx2; - cumulus.WllExtraSoilMoistureTx3 = settings.daviswll.soilLeaf.extraSoilMoist.soilMoistTx3; - cumulus.WllExtraSoilMoistureTx4 = settings.daviswll.soilLeaf.extraSoilMoist.soilMoistTx4; - - cumulus.WllExtraSoilTempIdx1 = settings.daviswll.soilLeaf.extraSoilTemp.soilTempIdx1; - cumulus.WllExtraSoilTempIdx2 = settings.daviswll.soilLeaf.extraSoilTemp.soilTempIdx2; - cumulus.WllExtraSoilTempIdx3 = settings.daviswll.soilLeaf.extraSoilTemp.soilTempIdx3; - cumulus.WllExtraSoilTempIdx4 = settings.daviswll.soilLeaf.extraSoilTemp.soilTempIdx4; - cumulus.WllExtraSoilTempTx1 = settings.daviswll.soilLeaf.extraSoilTemp.soilTempTx1; - cumulus.WllExtraSoilTempTx2 = settings.daviswll.soilLeaf.extraSoilTemp.soilTempTx2; - cumulus.WllExtraSoilTempTx3 = settings.daviswll.soilLeaf.extraSoilTemp.soilTempTx3; - cumulus.WllExtraSoilTempTx4 = settings.daviswll.soilLeaf.extraSoilTemp.soilTempTx4; - - cumulus.WllExtraTempTx[0] = settings.daviswll.extraTemp.extraTempTx1; - cumulus.WllExtraTempTx[1] = settings.daviswll.extraTemp.extraTempTx2; - cumulus.WllExtraTempTx[2] = settings.daviswll.extraTemp.extraTempTx3; - cumulus.WllExtraTempTx[3] = settings.daviswll.extraTemp.extraTempTx4; - cumulus.WllExtraTempTx[4] = settings.daviswll.extraTemp.extraTempTx5; - cumulus.WllExtraTempTx[5] = settings.daviswll.extraTemp.extraTempTx6; - cumulus.WllExtraTempTx[6] = settings.daviswll.extraTemp.extraTempTx7; - cumulus.WllExtraTempTx[7] = settings.daviswll.extraTemp.extraTempTx8; - - cumulus.WllExtraHumTx[0] = settings.daviswll.extraTemp.extraHumTx1; - cumulus.WllExtraHumTx[1] = settings.daviswll.extraTemp.extraHumTx2; - cumulus.WllExtraHumTx[2] = settings.daviswll.extraTemp.extraHumTx3; - cumulus.WllExtraHumTx[3] = settings.daviswll.extraTemp.extraHumTx4; - cumulus.WllExtraHumTx[4] = settings.daviswll.extraTemp.extraHumTx5; - cumulus.WllExtraHumTx[5] = settings.daviswll.extraTemp.extraHumTx6; - cumulus.WllExtraHumTx[6] = settings.daviswll.extraTemp.extraHumTx7; - cumulus.WllExtraHumTx[7] = settings.daviswll.extraTemp.extraHumTx8; + if (settings.daviswll != null) + { + cumulus.WLLAutoUpdateIpAddress = settings.daviswll.network.autoDiscover; + cumulus.WllApiKey = settings.daviswll.api.apiKey; + cumulus.WllApiSecret = settings.daviswll.api.apiSecret; + cumulus.WllStationId = settings.daviswll.api.apiStationId; + + cumulus.WllPrimaryRain = settings.daviswll.primary.rain; + cumulus.WllPrimarySolar = settings.daviswll.primary.solar; + cumulus.WllPrimaryTempHum = settings.daviswll.primary.temphum; + cumulus.WllPrimaryUV = settings.daviswll.primary.uv; + cumulus.WllPrimaryWind = settings.daviswll.primary.wind; + + cumulus.WllExtraLeafTx1 = settings.daviswll.soilLeaf.extraLeaf.leafTx1; + cumulus.WllExtraLeafTx2 = settings.daviswll.soilLeaf.extraLeaf.leafTx2; + cumulus.WllExtraLeafIdx1 = settings.daviswll.soilLeaf.extraLeaf.leafIdx1; + cumulus.WllExtraLeafIdx2 = settings.daviswll.soilLeaf.extraLeaf.leafIdx2; + + cumulus.WllExtraSoilMoistureIdx1 = settings.daviswll.soilLeaf.extraSoilMoist.soilMoistIdx1; + cumulus.WllExtraSoilMoistureIdx2 = settings.daviswll.soilLeaf.extraSoilMoist.soilMoistIdx2; + cumulus.WllExtraSoilMoistureIdx3 = settings.daviswll.soilLeaf.extraSoilMoist.soilMoistIdx3; + cumulus.WllExtraSoilMoistureIdx4 = settings.daviswll.soilLeaf.extraSoilMoist.soilMoistIdx4; + cumulus.WllExtraSoilMoistureTx1 = settings.daviswll.soilLeaf.extraSoilMoist.soilMoistTx1; + cumulus.WllExtraSoilMoistureTx2 = settings.daviswll.soilLeaf.extraSoilMoist.soilMoistTx2; + cumulus.WllExtraSoilMoistureTx3 = settings.daviswll.soilLeaf.extraSoilMoist.soilMoistTx3; + cumulus.WllExtraSoilMoistureTx4 = settings.daviswll.soilLeaf.extraSoilMoist.soilMoistTx4; + + cumulus.WllExtraSoilTempIdx1 = settings.daviswll.soilLeaf.extraSoilTemp.soilTempIdx1; + cumulus.WllExtraSoilTempIdx2 = settings.daviswll.soilLeaf.extraSoilTemp.soilTempIdx2; + cumulus.WllExtraSoilTempIdx3 = settings.daviswll.soilLeaf.extraSoilTemp.soilTempIdx3; + cumulus.WllExtraSoilTempIdx4 = settings.daviswll.soilLeaf.extraSoilTemp.soilTempIdx4; + cumulus.WllExtraSoilTempTx1 = settings.daviswll.soilLeaf.extraSoilTemp.soilTempTx1; + cumulus.WllExtraSoilTempTx2 = settings.daviswll.soilLeaf.extraSoilTemp.soilTempTx2; + cumulus.WllExtraSoilTempTx3 = settings.daviswll.soilLeaf.extraSoilTemp.soilTempTx3; + cumulus.WllExtraSoilTempTx4 = settings.daviswll.soilLeaf.extraSoilTemp.soilTempTx4; + + cumulus.WllExtraTempTx[0] = settings.daviswll.extraTemp.extraTempTx1; + cumulus.WllExtraTempTx[1] = settings.daviswll.extraTemp.extraTempTx2; + cumulus.WllExtraTempTx[2] = settings.daviswll.extraTemp.extraTempTx3; + cumulus.WllExtraTempTx[3] = settings.daviswll.extraTemp.extraTempTx4; + cumulus.WllExtraTempTx[4] = settings.daviswll.extraTemp.extraTempTx5; + cumulus.WllExtraTempTx[5] = settings.daviswll.extraTemp.extraTempTx6; + cumulus.WllExtraTempTx[6] = settings.daviswll.extraTemp.extraTempTx7; + cumulus.WllExtraTempTx[7] = settings.daviswll.extraTemp.extraTempTx8; + + cumulus.WllExtraHumTx[0] = settings.daviswll.extraTemp.extraHumTx1; + cumulus.WllExtraHumTx[1] = settings.daviswll.extraTemp.extraHumTx2; + cumulus.WllExtraHumTx[2] = settings.daviswll.extraTemp.extraHumTx3; + cumulus.WllExtraHumTx[3] = settings.daviswll.extraTemp.extraHumTx4; + cumulus.WllExtraHumTx[4] = settings.daviswll.extraTemp.extraHumTx5; + cumulus.WllExtraHumTx[5] = settings.daviswll.extraTemp.extraHumTx6; + cumulus.WllExtraHumTx[6] = settings.daviswll.extraTemp.extraHumTx7; + cumulus.WllExtraHumTx[7] = settings.daviswll.extraTemp.extraHumTx8; + } } catch (Exception ex) { @@ -544,7 +693,7 @@ internal string UpdateStationConfig(IHttpContext context) // log interval try { - cumulus.DataLogInterval = settings.loginterval; + cumulus.DataLogInterval = settings.general.loginterval; } catch (Exception ex) { @@ -558,7 +707,7 @@ internal string UpdateStationConfig(IHttpContext context) // com port try { - cumulus.ComportName = settings.comportname ?? string.Empty; + cumulus.ComportName = settings.general.comportname ?? cumulus.ComportName; } catch (Exception ex) { @@ -568,13 +717,20 @@ internal string UpdateStationConfig(IHttpContext context) context.Response.StatusCode = 500; } - // Davis connection details + // Davis Common details try { - cumulus.VP2ConnectionType = settings.davisconn.conntype; - cumulus.VP2IPAddr = settings.davisconn.tcpsettings.ipaddress ?? string.Empty; - cumulus.VP2TCPPort = settings.davisconn.tcpsettings.tcpport; - cumulus.VP2PeriodicDisconnectInterval = settings.davisconn.tcpsettings.disconperiod; + if (settings.daviscommon != null) + { + cumulus.DavisOptions.ConnectionType = settings.daviscommon.davisconn.conntype; + if (settings.daviscommon.davisconn.tcpsettings != null) + { + cumulus.DavisOptions.IPAddr = settings.daviscommon.davisconn.tcpsettings.ipaddress ?? string.Empty; + cumulus.DavisOptions.TCPPort = settings.daviscommon.davisconn.tcpsettings.tcpport; + cumulus.DavisOptions.PeriodicDisconnectInterval = settings.daviscommon.davisconn.tcpsettings.disconperiod; + cumulus.DavisOptions.RainGaugeType = settings.daviscommon.advanced.raingaugetype; + } + } } catch (Exception ex) { @@ -587,9 +743,12 @@ internal string UpdateStationConfig(IHttpContext context) // GW1000 connection details try { - cumulus.Gw1000IpAddress = settings.gw1000.ipaddress; - cumulus.Gw1000AutoUpdateIpAddress = settings.gw1000.autoDiscover; - cumulus.Gw1000MacAddress = settings.gw1000.macaddress; + if (settings.gw1000 != null) + { + cumulus.Gw1000IpAddress = settings.gw1000.ipaddress; + cumulus.Gw1000AutoUpdateIpAddress = settings.gw1000.autoDiscover; + cumulus.Gw1000MacAddress = settings.gw1000.macaddress; + } } catch (Exception ex) { @@ -599,14 +758,82 @@ internal string UpdateStationConfig(IHttpContext context) context.Response.StatusCode = 500; } + // EasyWeather + try + { + if (settings.easyw != null) + { + cumulus.EwOptions.Interval = settings.easyw.interval; + cumulus.EwOptions.Filename = settings.easyw.filename; + cumulus.EwOptions.MinPressMB = settings.easyw.minpressmb; + cumulus.EwOptions.MaxPressMB = settings.easyw.maxpressmb; + cumulus.EwOptions.MaxRainTipDiff = settings.easyw.raintipdiff; + cumulus.EwOptions.PressOffset = settings.easyw.pressoffset; + } + } + catch (Exception ex) + { + var msg = "Error processing EasyWeather settings: " + ex.Message; + cumulus.LogMessage(msg); + errorMsg += msg + "\n\n"; + context.Response.StatusCode = 500; + } + + // FineOffset + try + { + if (settings.fineoffset != null) + { + cumulus.FineOffsetOptions.FineOffsetSyncReads = settings.fineoffset.syncreads; + cumulus.FineOffsetOptions.FineOffsetReadTime = settings.fineoffset.readtime; + cumulus.FineOffsetOptions.FineOffsetReadAvoidPeriod = settings.fineoffset.readavoid; + } + } + catch (Exception ex) + { + var msg = "Error processing Fine Offset settings: " + ex.Message; + cumulus.LogMessage(msg); + errorMsg += msg + "\n\n"; + context.Response.StatusCode = 500; + } + + // Instromet + try + { + if (settings.imet != null) + { + cumulus.ImetOptions.ImetBaudRate = settings.imet.baudrate; + cumulus.ImetOptions.ImetReadDelay = settings.imet.advanced.readdelay; + cumulus.ImetOptions.ImetWaitTime = settings.imet.advanced.waittime; + cumulus.ImetOptions.ImetUpdateLogPointer = settings.imet.advanced.updatelogpointer; + } + } + catch (Exception ex) + { + var msg = "Error processing Instromet settings: " + ex.Message; + cumulus.LogMessage(msg); + errorMsg += msg + "\n\n"; + context.Response.StatusCode = 500; + } + // Units try { - cumulus.WindUnit = settings.units.wind; - cumulus.PressUnit = settings.units.pressure; - cumulus.TempUnit = settings.units.temp; - cumulus.RainUnit = settings.units.rain; + cumulus.Units.Wind = settings.general.units.wind; + cumulus.Units.Press = settings.general.units.pressure; + cumulus.TempUnit = settings.general.units.temp; + cumulus.RainUnit = settings.general.units.rain; cumulus.SetupUnitText(); + + cumulus.AirQualityDPlaces = settings.general.units.advanced.airqulaitydp; + cumulus.PressDPlaces = settings.general.units.advanced.pressdp; + cumulus.RainDPlaces = settings.general.units.advanced.raindp; + cumulus.SunshineDPlaces = settings.general.units.advanced.sunshinedp; + cumulus.TempDPlaces = settings.general.units.advanced.tempdp; + cumulus.UVDPlaces = settings.general.units.advanced.uvdp; + cumulus.WindAvgDPlaces = settings.general.units.advanced.windavgdp; + cumulus.WindDPlaces = settings.general.units.advanced.winddp; + cumulus.WindRunDPlaces = settings.general.units.advanced.windrundp; } catch (Exception ex) { @@ -619,12 +846,12 @@ internal string UpdateStationConfig(IHttpContext context) // Station type try { - if (cumulus.StationType != settings.stationtype) + if (cumulus.StationType != settings.general.stationtype) { cumulus.LogMessage("Station type changed, restart required"); cumulus.LogConsoleMessage("*** Station type changed, restart required ***"); } - cumulus.StationType = settings.stationtype; + cumulus.StationType = settings.general.stationtype; } catch (Exception ex) { @@ -766,28 +993,61 @@ internal string GetVersion() internal class JsonStationSettingsData { - public int stationtype { get; set; } - public JsonStationSettingsUnits units { get; set; } - public JsonStationSettingsDavisConn davisconn { set; get; } + public int stationid { get; set; } + public JsonStationGeneral general { get; set; } + public JsonStationSettingsDavisCommon daviscommon { set; get; } + public JsonStationSettingsDavisVp2 davisvp2 { get; set; } public JSonStationSettingsGw1000Conn gw1000 { get; set; } public JsonStationSettingsWLL daviswll { get; set; } - public string comportname { get; set; } - public int loginterval { get; set; } - public JsonStationSettingsLogRollover logrollover { get; set; } + public JsonStationSettingsFineOffset fineoffset { get; set; } + public JsonStationSettingsEasyWeather easyw { get; set; } + public JsonStationSettingsImet imet { get; set; } public JsonStationSettingsOptions Options { get; set; } - public JsonStationSettingsLocation Location { get; set; } public JsonStationSettingsForecast Forecast { get; set; } public JsonStationSettingsSolar Solar { get; set; } public JsonStationSettingsAnnualRainfall AnnualRainfall { get; set; } public JsonStationSettingsGraphs Graphs { get; set; } } + internal class JsonStationGeneral + { + public int stationtype { get; set; } + public string comportname { get; set; } + public int loginterval { get; set; } + public JsonStationSettingsLogRollover logrollover { get; set; } + public JsonStationSettingsUnits units { get; set; } + public JsonStationSettingsLocation Location { get; set; } + } + + + internal class JsonStationSettingsUnitsAdvanced + { + public int uvdp { get; set; } + public int raindp { get; set; } + public int tempdp { get; set; } + public int pressdp { get; set; } + public int winddp { get; set; } + public int windavgdp { get; set; } + public int windrundp { get; set; } + public int sunshinedp { get; set; } + public int airqulaitydp { get; set; } + + } + internal class JsonStationSettingsUnits { public int wind { get; set; } public int pressure { get; set; } public int temp { get; set; } public int rain { get; set; } + public JsonStationSettingsUnitsAdvanced advanced { get; set; } + } + + internal class JsonStationSettingsOptionsAdvanced + { + public int avgbearingmins { get; set; } + public int avgspeedmins { get; set; } + public int peakgustmins { get; set; } } internal class JsonStationSettingsOptions @@ -799,16 +1059,16 @@ internal class JsonStationSettingsOptions public bool calculatedewpoint { get; set; } public bool calculatewindchill { get; set; } public bool syncstationclock { get; set; } + public int syncclockhour { get; set; } public bool cumuluspresstrendnames { get; set; } - public bool vp1minbarupdate { get; set; } public bool roundwindspeeds { get; set; } public bool ignorelacrosseclock { get; set; } public bool extrasensors { get; set; } - public bool synchroniseforeads { get; set; } public bool debuglogging { get; set; } public bool datalogging { get; set; } public bool stopsecondinstance { get; set; } - public bool readreceptionstats { get; set; } + public bool nosensorcheck { get; set; } + public JsonStationSettingsOptionsAdvanced advanced { get; set; } } internal class JsonStationSettingsTCPsettings @@ -818,12 +1078,56 @@ internal class JsonStationSettingsTCPsettings public int disconperiod { get; set; } } + internal class JsonStationSettingsDavisCommon + { + public JsonStationSettingsDavisConn davisconn { get; set; } + public JsonStationSettingsDavisCommonAdvanced advanced { get; set; } + } + internal class JsonStationSettingsDavisConn { public int conntype { get; set; } public JsonStationSettingsTCPsettings tcpsettings { get; set; } } + internal class JsonStationSettingsDavisCommonAdvanced + { + public int raingaugetype { get; set; } + } + + internal class JsonStationSettingsDavisVp2 + { + public bool readreceptionstats { get; set; } + public bool setloggerinterval { get; set; } + public JsonStationSettingsDavisVp2Advanced advanced { get; set; } + } + + internal class JsonStationSettingsDavisVp2Advanced + { + public bool useloop2 { get; set; } + public bool vp1minbarupdate { get; set; } + public int initwaittime { get; set; } + public int ipresponsetime { get; set; } + public int baudrate { get; set; } + } + + internal class JsonStationSettingsFineOffset + { + public bool syncreads { get; set; } + public int readavoid { get; set; } + public int readtime { get; set; } + } + + internal class JsonStationSettingsEasyWeather + { + public double interval { get; set; } + public string filename { get; set; } + public int minpressmb { get; set; } + public int maxpressmb { get; set; } + public int raintipdiff { get; set; } + public double pressoffset { get; set; } + } + internal class JSonStationSettingsGw1000Conn { public string ipaddress { get; set; } @@ -831,6 +1135,19 @@ internal class JSonStationSettingsGw1000Conn public string macaddress { get; set; } } + internal class JsonStationSettingsImet + { + public int baudrate { get; set; } + public JsonStationSettingsImetAdvanced advanced { get; set; } + } + + internal class JsonStationSettingsImetAdvanced + { + public int waittime { get; set; } + public int readdelay { get; set; } + public bool updatelogpointer { get; set; } + } + internal class JsonStationSettingsLogRollover { public string time { get; set; } @@ -975,6 +1292,19 @@ public class JsonStationSettingsGraphs { public int graphhours { get; set; } public int graphdays { get; set; } + + public JsonStationSettingsGraphVisibility datavisibility { get; set; } + } + + public class JsonStationSettingsGraphVisibility + { + public JsonStationSettingsGraphDataTemperature temperature { get; set; } + public JsonStationSettingsGraphDataHumidity humidity { get; set; } + public JsonStationSettingsGraphDataSolar solar { get; set; } + } + + public class JsonStationSettingsGraphDataTemperature + { public bool graphTempVis { get; set; } public bool graphInTempVis { get; set; } public bool graphHeatIndexVis { get; set; } @@ -983,8 +1313,16 @@ public class JsonStationSettingsGraphs public bool graphAppTempVis { get; set; } public bool graphFeelsLikeVis { get; set; } public bool graphHumidexVis { get; set; } + } + + public class JsonStationSettingsGraphDataHumidity + { public bool graphHumVis { get; set; } public bool graphInHumVis { get; set; } + } + + public class JsonStationSettingsGraphDataSolar + { public bool graphUvVis { get; set; } public bool graphSolarVis { get; set; } public bool graphSunshineVis { get; set; } diff --git a/CumulusMX/WMR200Station.cs b/CumulusMX/WMR200Station.cs index e561dffa..8e9fd0f6 100644 --- a/CumulusMX/WMR200Station.cs +++ b/CumulusMX/WMR200Station.cs @@ -1446,7 +1446,7 @@ private void ProcessHistoryDataPacket() DoWind(ConvertWindMSToUser(gust),bearing,ConvertWindMSToUser(average),timestamp); // add in 'interval' minutes worth of wind speed to windrun - WindRunToday += (WindAverage*WindRunHourMult[cumulus.WindUnit]*interval*60)/1000.0; + WindRunToday += (WindAverage*WindRunHourMult[cumulus.Units.Wind]*interval*60)/1000.0; // update dominant wind bearing CalculateDominantWindBearing(Bearing, WindAverage, interval); int sensorcount = packetBuffer[32]; diff --git a/CumulusMX/WS2300Station.cs b/CumulusMX/WS2300Station.cs index e372350f..349ace36 100644 --- a/CumulusMX/WS2300Station.cs +++ b/CumulusMX/WS2300Station.cs @@ -354,10 +354,10 @@ private void ProcessHistoryData() } // Wind run ====================================================================== - cumulus.LogMessage("Windrun: " + WindAverage.ToString(cumulus.WindAvgFormat) + cumulus.WindUnitText + " for " + historydata.interval + " minutes = " + - (WindAverage * WindRunHourMult[cumulus.WindUnit] * historydata.interval / 60.0).ToString(cumulus.WindRunFormat) + cumulus.WindRunUnitText); + cumulus.LogMessage("Windrun: " + WindAverage.ToString(cumulus.WindAvgFormat) + cumulus.Units.WindText + " for " + historydata.interval + " minutes = " + + (WindAverage * WindRunHourMult[cumulus.Units.Wind] * historydata.interval / 60.0).ToString(cumulus.WindRunFormat) + cumulus.Units.WindRunText); - WindRunToday += (WindAverage * WindRunHourMult[cumulus.WindUnit] * historydata.interval / 60.0); + WindRunToday += (WindAverage * WindRunHourMult[cumulus.Units.Wind] * historydata.interval / 60.0); CheckForWindrunHighLow(timestamp); diff --git a/CumulusMX/WeatherStation.cs b/CumulusMX/WeatherStation.cs index 1d21fa73..0d87f87b 100644 --- a/CumulusMX/WeatherStation.cs +++ b/CumulusMX/WeatherStation.cs @@ -603,7 +603,7 @@ public void ReadTodayFile() FOSensorClockTime = ini.GetValue("FineOffset", "FOSensorClockTime", DateTime.MinValue); FOStationClockTime = ini.GetValue("FineOffset", "FOStationClockTime", DateTime.MinValue); - if (cumulus.StationOptions.SyncFOReads) + if (cumulus.FineOffsetOptions.FineOffsetSyncReads) { cumulus.LogMessage("Sensor clock " + FOSensorClockTime.ToLongTimeString()); cumulus.LogMessage("Station clock " + FOStationClockTime.ToLongTimeString()); @@ -952,7 +952,7 @@ public void UpdatePressureTrendString() { double threeHourlyPressureChangeMb = 0; - switch (cumulus.PressUnit) + switch (cumulus.Units.Press) { case 0: case 1: @@ -1461,10 +1461,10 @@ public void SecondTimer(object sender, ElapsedEventArgs e) var data = new DataStruct(cumulus, OutdoorTemperature, OutdoorHumidity, TempTotalToday / tempsamplestoday, IndoorTemperature, OutdoorDewpoint, WindChill, IndoorHumidity, Pressure, WindLatest, WindAverage, RecentMaxGust, WindRunToday, Bearing, AvgBearing, RainToday, RainYesterday, RainMonth, RainYear, RainRate, RainLastHour, HeatIndex, Humidex, ApparentTemperature, temptrendval, presstrendval, HiLoToday.HighGust, HiLoToday.HighGustTime.ToString("HH:mm"), HiLoToday.HighWind, - HiLoToday.HighGustBearing, cumulus.WindUnitText, BearingRangeFrom10, BearingRangeTo10, windRoseData.ToString(), HiLoToday.HighTemp, HiLoToday.LowTemp, + HiLoToday.HighGustBearing, cumulus.Units.WindText, BearingRangeFrom10, BearingRangeTo10, windRoseData.ToString(), HiLoToday.HighTemp, HiLoToday.LowTemp, HiLoToday.HighTempTime.ToString("HH:mm"), HiLoToday.LowTempTime.ToString("HH:mm"), HiLoToday.HighPress, HiLoToday.LowPress, HiLoToday.HighPressTime.ToString("HH:mm"), HiLoToday.LowPressTime.ToString("HH:mm"), HiLoToday.HighRainRate, HiLoToday.HighRainRateTime.ToString("HH:mm"), HiLoToday.HighHumidity, HiLoToday.LowHumidity, - HiLoToday.HighHumidityTime.ToString("HH:mm"), HiLoToday.LowHumidityTime.ToString("HH:mm"), cumulus.PressUnitText, cumulus.TempUnitText, cumulus.RainUnitText, + HiLoToday.HighHumidityTime.ToString("HH:mm"), HiLoToday.LowHumidityTime.ToString("HH:mm"), cumulus.Units.PressText, cumulus.Units.TempText, cumulus.Units.RainText, HiLoToday.HighDewPoint, HiLoToday.LowDewPoint, HiLoToday.HighDewPointTime.ToString("HH:mm"), HiLoToday.LowDewPointTime.ToString("HH:mm"), HiLoToday.LowWindChill, HiLoToday.LowWindChillTime.ToString("HH:mm"), (int)SolarRad, (int)HiLoToday.HighSolar, HiLoToday.HighSolarTime.ToString("HH:mm"), UV, HiLoToday.HighUv, HiLoToday.HighUvTime.ToString("HH:mm"), forecaststr, getTimeString(cumulus.SunRiseTime), getTimeString(cumulus.SunSetTime), @@ -1629,11 +1629,11 @@ private void MinuteChanged(DateTime now) if (!DataStopped) { CurrentSolarMax = AstroLib.SolarMax(now, cumulus.Longitude, cumulus.Latitude, AltitudeM(cumulus.Altitude), out SolarElevation, cumulus.RStransfactor, cumulus.BrasTurbidity, cumulus.SolarCalc); - if (((Pressure > 0) && TempReadyToPlot && WindReadyToPlot) || cumulus.NoSensorCheck) + if (((Pressure > 0) && TempReadyToPlot && WindReadyToPlot) || cumulus.StationOptions.NoSensorCheck) { // increment wind run by one minute's worth of average speed - WindRunToday += (WindAverage * WindRunHourMult[cumulus.WindUnit] / 60.0); + WindRunToday += (WindAverage * WindRunHourMult[cumulus.Units.Wind] / 60.0); CheckForWindrunHighLow(now); @@ -1862,7 +1862,7 @@ private void MinuteChanged(DateTime now) { var raw = File.ReadAllText(@"/sys/class/thermal/thermal_zone0/temp"); cumulus.CPUtemp = ConvertTempCToUser(double.Parse(raw) / 1000); - cumulus.LogDebugMessage($"Current CPU temp = {cumulus.CPUtemp.ToString(cumulus.TempFormat)}{cumulus.TempUnitText}"); + cumulus.LogDebugMessage($"Current CPU temp = {cumulus.CPUtemp.ToString(cumulus.TempFormat)}{cumulus.Units.TempText}"); } catch (Exception ex) { @@ -2812,7 +2812,7 @@ private double ConvertUserRainToIn(double value) public double ConvertUserWindToMPH(double value) { - switch (cumulus.WindUnit) + switch (cumulus.Units.Wind) { case 0: return value * 2.23693629; @@ -3451,7 +3451,7 @@ public void DoPressure(double sl, DateTime timestamp) Pressure = sl * cumulus.Calib.Press.Mult + cumulus.Calib.Press.Offset; if (cumulus.Manufacturer == cumulus.DAVIS) { - if (!cumulus.UseDavisLoop2) + if (!cumulus.DavisOptions.UseLoop2) { // Loop2 data not available, just use sea level (for now, anyway) AltimeterPressure = Pressure; @@ -3576,7 +3576,7 @@ public void DoRain(double total, double rate, DateTime timestamp) if (cumulus.Manufacturer == cumulus.DAVIS) // Davis can have either 0.2mm or 0.01in buckets, and the user could select to measure in mm or inches! { // If the bucket size is set, use that, otherwise infer from rain units - var bucketSize = cumulus.VPrainGaugeType == -1 ? cumulus.RainUnit : cumulus.VPrainGaugeType; + var bucketSize = cumulus.DavisOptions.RainGaugeType == -1 ? cumulus.RainUnit : cumulus.DavisOptions.RainGaugeType; if (bucketSize == 0) // 0.2 mm tips { @@ -3915,7 +3915,7 @@ public double AltitudeM(double altitude) /// public double PressureHPa(double value) { - if (cumulus.PressUnit == 2) + if (cumulus.Units.Press == 2) return value / 0.0295333727; else return value; @@ -5767,7 +5767,7 @@ public double ConvertUserTempToF(double value) /// Wind in configured units public double ConvertWindMSToUser(double value) { - switch (cumulus.WindUnit) + switch (cumulus.Units.Wind) { case 0: return value; @@ -5789,7 +5789,7 @@ public double ConvertWindMSToUser(double value) /// Wind in configured units public double ConvertWindMPHToUser(double value) { - switch (cumulus.WindUnit) + switch (cumulus.Units.Wind) { case 0: return value * 0.44704; @@ -5811,7 +5811,7 @@ public double ConvertWindMPHToUser(double value) /// public virtual double ConvertUserWindToMS(double value) { - switch (cumulus.WindUnit) + switch (cumulus.Units.Wind) { case 0: return value; @@ -5833,7 +5833,7 @@ public virtual double ConvertUserWindToMS(double value) /// Wind in configured units public double ConvertKmtoUserUnits(double val) { - switch (cumulus.WindUnit) + switch (cumulus.Units.Wind) { case 0: // m/s case 2: // km/h @@ -5853,7 +5853,7 @@ public double ConvertKmtoUserUnits(double val) /// Wind in km public virtual double ConvertWindRunToKm(double value) { - switch (cumulus.WindUnit) + switch (cumulus.Units.Wind) { case 0: // m/s case 2: // km/h @@ -5867,9 +5867,9 @@ public virtual double ConvertWindRunToKm(double value) } } - public double ConvertUserWindToKPH(double wind) // input is in WindUnit units, convert to km/h + public double ConvertUserWindToKPH(double wind) // input is in Units.Wind units, convert to km/h { - switch (cumulus.WindUnit) + switch (cumulus.Units.Wind) { case 0: // m/s return wind * 3.6; @@ -5921,7 +5921,7 @@ public virtual double ConvertUserRainToMM(double value) /// pressure in configured units public double ConvertPressMBToUser(double value) { - return cumulus.PressUnit == 2 ? value * 0.0295333727 : value; + return cumulus.Units.Press == 2 ? value * 0.0295333727 : value; } /// @@ -5931,7 +5931,7 @@ public double ConvertPressMBToUser(double value) /// pressure in configured units public double ConvertPressINHGToUser(double value) { - return cumulus.PressUnit == 2 ? value : value * 33.8638866667; + return cumulus.Units.Press == 2 ? value : value * 33.8638866667; } /// @@ -5941,7 +5941,7 @@ public double ConvertPressINHGToUser(double value) /// pressure in mb public double ConvertUserPressToMB(double value) { - return cumulus.PressUnit == 2 ? value / 0.0295333727 : value; + return cumulus.Units.Press == 2 ? value / 0.0295333727 : value; } /// @@ -5951,7 +5951,7 @@ public double ConvertUserPressToMB(double value) /// pressure in mb public double ConvertUserPressToIN(double value) { - return cumulus.PressUnit == 2 ? value : value * 0.0295333727; + return cumulus.Units.Press == 2 ? value : value * 0.0295333727; } public string CompassPoint(int bearing) @@ -8675,7 +8675,7 @@ public string GetAwekasURLv4(out string pwstring, DateTime timestamp) double threeHourlyPressureChangeMb = 0; - switch (cumulus.PressUnit) + switch (cumulus.Units.Press) { case 0: case 1: @@ -9225,21 +9225,21 @@ public string GetTempRecords() { var json = new StringBuilder("{\"data\":[", 2048); - json.Append(alltimejsonformat(AllTime.HighTemp, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f") + ","); - json.Append(alltimejsonformat(AllTime.LowTemp, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f") + ","); - json.Append(alltimejsonformat(AllTime.HighDewPoint, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f") + ","); - json.Append(alltimejsonformat(AllTime.LowDewPoint, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f") + ","); - json.Append(alltimejsonformat(AllTime.HighAppTemp, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f") + ","); - json.Append(alltimejsonformat(AllTime.LowAppTemp, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f") + ","); - json.Append(alltimejsonformat(AllTime.HighFeelsLike, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f") + ","); - json.Append(alltimejsonformat(AllTime.LowFeelsLike, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f") + ","); + json.Append(alltimejsonformat(AllTime.HighTemp, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f") + ","); + json.Append(alltimejsonformat(AllTime.LowTemp, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f") + ","); + json.Append(alltimejsonformat(AllTime.HighDewPoint, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f") + ","); + json.Append(alltimejsonformat(AllTime.LowDewPoint, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f") + ","); + json.Append(alltimejsonformat(AllTime.HighAppTemp, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f") + ","); + json.Append(alltimejsonformat(AllTime.LowAppTemp, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f") + ","); + json.Append(alltimejsonformat(AllTime.HighFeelsLike, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f") + ","); + json.Append(alltimejsonformat(AllTime.LowFeelsLike, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f") + ","); json.Append(alltimejsonformat(AllTime.HighHumidex, " ", cumulus.TempFormat, "f") + ","); - json.Append(alltimejsonformat(AllTime.LowChill, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f") + ","); - json.Append(alltimejsonformat(AllTime.HighHeatIndex, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f") + ","); - json.Append(alltimejsonformat(AllTime.HighMinTemp, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f") + ","); - json.Append(alltimejsonformat(AllTime.LowMaxTemp, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f") + ","); - json.Append(alltimejsonformat(AllTime.HighDailyTempRange, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "D") + ","); - json.Append(alltimejsonformat(AllTime.LowDailyTempRange, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "D")); + json.Append(alltimejsonformat(AllTime.LowChill, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f") + ","); + json.Append(alltimejsonformat(AllTime.HighHeatIndex, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f") + ","); + json.Append(alltimejsonformat(AllTime.HighMinTemp, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f") + ","); + json.Append(alltimejsonformat(AllTime.LowMaxTemp, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f") + ","); + json.Append(alltimejsonformat(AllTime.HighDailyTempRange, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "D") + ","); + json.Append(alltimejsonformat(AllTime.LowDailyTempRange, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "D")); json.Append("]}"); return json.ToString(); } @@ -9259,9 +9259,9 @@ public string GetPressRecords() { var json = new StringBuilder("{\"data\":[", 512); - json.Append(alltimejsonformat(AllTime.HighPress, cumulus.PressUnitText, cumulus.PressFormat, "f")); + json.Append(alltimejsonformat(AllTime.HighPress, cumulus.Units.PressText, cumulus.PressFormat, "f")); json.Append(","); - json.Append(alltimejsonformat(AllTime.LowPress, cumulus.PressUnitText, cumulus.PressFormat, "f")); + json.Append(alltimejsonformat(AllTime.LowPress, cumulus.Units.PressText, cumulus.PressFormat, "f")); json.Append("]}"); return json.ToString(); } @@ -9270,11 +9270,11 @@ public string GetWindRecords() { var json = new StringBuilder("{\"data\":[", 512); - json.Append(alltimejsonformat(AllTime.HighGust, cumulus.WindUnitText, cumulus.WindFormat, "f")); + json.Append(alltimejsonformat(AllTime.HighGust, cumulus.Units.WindText, cumulus.WindFormat, "f")); json.Append(","); - json.Append(alltimejsonformat(AllTime.HighWind, cumulus.WindUnitText, cumulus.WindAvgFormat, "f")); + json.Append(alltimejsonformat(AllTime.HighWind, cumulus.Units.WindText, cumulus.WindAvgFormat, "f")); json.Append(","); - json.Append(alltimejsonformat(AllTime.HighWindRun, cumulus.WindRunUnitText, cumulus.WindRunFormat, "D")); + json.Append(alltimejsonformat(AllTime.HighWindRun, cumulus.Units.WindRunText, cumulus.WindRunFormat, "D")); json.Append("]}"); return json.ToString(); } @@ -9283,13 +9283,13 @@ public string GetRainRecords() { var json = new StringBuilder("{\"data\":[", 512); - json.Append(alltimejsonformat(AllTime.HighRainRate, cumulus.RainUnitText + "/hr", cumulus.RainFormat, "f")); + json.Append(alltimejsonformat(AllTime.HighRainRate, cumulus.Units.RainText + "/hr", cumulus.RainFormat, "f")); json.Append(","); - json.Append(alltimejsonformat(AllTime.HourlyRain, cumulus.RainUnitText, cumulus.RainFormat, "f")); + json.Append(alltimejsonformat(AllTime.HourlyRain, cumulus.Units.RainText, cumulus.RainFormat, "f")); json.Append(","); - json.Append(alltimejsonformat(AllTime.DailyRain, cumulus.RainUnitText, cumulus.RainFormat, "D")); + json.Append(alltimejsonformat(AllTime.DailyRain, cumulus.Units.RainText, cumulus.RainFormat, "D")); json.Append(","); - json.Append(alltimejsonformat(AllTime.MonthlyRain, cumulus.RainUnitText, cumulus.RainFormat, "Y")); + json.Append(alltimejsonformat(AllTime.MonthlyRain, cumulus.Units.RainText, cumulus.RainFormat, "Y")); json.Append(","); json.Append(alltimejsonformat(AllTime.LongestDryPeriod, "days", "f0", "D")); json.Append(","); @@ -9307,35 +9307,35 @@ public string GetMonthlyTempRecords(int month) { var json = new StringBuilder("{\"data\":[", 1024); - json.Append(monthlyjsonformat(MonthlyRecs[month].HighTemp, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthlyjsonformat(MonthlyRecs[month].HighTemp, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthlyjsonformat(MonthlyRecs[month].LowTemp, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthlyjsonformat(MonthlyRecs[month].LowTemp, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthlyjsonformat(MonthlyRecs[month].HighDewPoint, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthlyjsonformat(MonthlyRecs[month].HighDewPoint, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthlyjsonformat(MonthlyRecs[month].LowDewPoint, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthlyjsonformat(MonthlyRecs[month].LowDewPoint, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthlyjsonformat(MonthlyRecs[month].HighAppTemp, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthlyjsonformat(MonthlyRecs[month].HighAppTemp, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthlyjsonformat(MonthlyRecs[month].LowAppTemp, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthlyjsonformat(MonthlyRecs[month].LowAppTemp, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthlyjsonformat(MonthlyRecs[month].HighFeelsLike, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthlyjsonformat(MonthlyRecs[month].HighFeelsLike, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthlyjsonformat(MonthlyRecs[month].LowFeelsLike, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthlyjsonformat(MonthlyRecs[month].LowFeelsLike, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); json.Append(monthlyjsonformat(MonthlyRecs[month].HighHumidex, " ", cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthlyjsonformat(MonthlyRecs[month].LowChill, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthlyjsonformat(MonthlyRecs[month].LowChill, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthlyjsonformat(MonthlyRecs[month].HighHeatIndex, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthlyjsonformat(MonthlyRecs[month].HighHeatIndex, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthlyjsonformat(MonthlyRecs[month].HighMinTemp, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthlyjsonformat(MonthlyRecs[month].HighMinTemp, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthlyjsonformat(MonthlyRecs[month].LowMaxTemp, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthlyjsonformat(MonthlyRecs[month].LowMaxTemp, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthlyjsonformat(MonthlyRecs[month].HighDailyTempRange, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "D")); + json.Append(monthlyjsonformat(MonthlyRecs[month].HighDailyTempRange, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "D")); json.Append(","); - json.Append(monthlyjsonformat(MonthlyRecs[month].LowDailyTempRange, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "D")); + json.Append(monthlyjsonformat(MonthlyRecs[month].LowDailyTempRange, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "D")); json.Append("]}"); return json.ToString(); } @@ -9355,9 +9355,9 @@ public string GetMonthlyPressRecords(int month) { var json = new StringBuilder("{\"data\":[", 256); - json.Append(monthlyjsonformat(MonthlyRecs[month].HighPress, cumulus.PressUnitText, cumulus.PressFormat, "f")); + json.Append(monthlyjsonformat(MonthlyRecs[month].HighPress, cumulus.Units.PressText, cumulus.PressFormat, "f")); json.Append(","); - json.Append(monthlyjsonformat(MonthlyRecs[month].LowPress, cumulus.PressUnitText, cumulus.PressFormat, "f")); + json.Append(monthlyjsonformat(MonthlyRecs[month].LowPress, cumulus.Units.PressText, cumulus.PressFormat, "f")); json.Append("]}"); return json.ToString(); } @@ -9366,11 +9366,11 @@ public string GetMonthlyWindRecords(int month) { var json = new StringBuilder("{\"data\":[", 256); - json.Append(monthlyjsonformat(MonthlyRecs[month].HighGust, cumulus.WindUnitText, cumulus.WindFormat, "f")); + json.Append(monthlyjsonformat(MonthlyRecs[month].HighGust, cumulus.Units.WindText, cumulus.WindFormat, "f")); json.Append(","); - json.Append(monthlyjsonformat(MonthlyRecs[month].HighWind, cumulus.WindUnitText, cumulus.WindAvgFormat, "f")); + json.Append(monthlyjsonformat(MonthlyRecs[month].HighWind, cumulus.Units.WindText, cumulus.WindAvgFormat, "f")); json.Append(","); - json.Append(monthlyjsonformat(MonthlyRecs[month].HighWindRun, cumulus.WindRunUnitText, cumulus.WindRunFormat, "D")); + json.Append(monthlyjsonformat(MonthlyRecs[month].HighWindRun, cumulus.Units.WindRunText, cumulus.WindRunFormat, "D")); json.Append("]}"); return json.ToString(); } @@ -9379,13 +9379,13 @@ public string GetMonthlyRainRecords(int month) { var json = new StringBuilder("{\"data\":[", 512); - json.Append(monthlyjsonformat(MonthlyRecs[month].HighRainRate, cumulus.RainUnitText + "/hr", cumulus.RainFormat, "f")); + json.Append(monthlyjsonformat(MonthlyRecs[month].HighRainRate, cumulus.Units.RainText + "/hr", cumulus.RainFormat, "f")); json.Append(","); - json.Append(monthlyjsonformat(MonthlyRecs[month].HourlyRain, cumulus.RainUnitText, cumulus.RainFormat, "f")); + json.Append(monthlyjsonformat(MonthlyRecs[month].HourlyRain, cumulus.Units.RainText, cumulus.RainFormat, "f")); json.Append(","); - json.Append(monthlyjsonformat(MonthlyRecs[month].DailyRain, cumulus.RainUnitText, cumulus.RainFormat, "D")); + json.Append(monthlyjsonformat(MonthlyRecs[month].DailyRain, cumulus.Units.RainText, cumulus.RainFormat, "D")); json.Append(","); - json.Append(monthlyjsonformat(MonthlyRecs[month].MonthlyRain, cumulus.RainUnitText, cumulus.RainFormat, "Y")); + json.Append(monthlyjsonformat(MonthlyRecs[month].MonthlyRain, cumulus.Units.RainText, cumulus.RainFormat, "Y")); json.Append(","); json.Append(monthlyjsonformat(MonthlyRecs[month].LongestDryPeriod, "days", "f0", "D")); json.Append(","); @@ -9403,35 +9403,35 @@ public string GetThisMonthTempRecords() { var json = new StringBuilder("{\"data\":[", 1024); - json.Append(monthyearjsonformat(ThisMonth.HighTemp.Desc, ThisMonth.HighTemp.Val, ThisMonth.HighTemp.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisMonth.HighTemp.Desc, ThisMonth.HighTemp.Val, ThisMonth.HighTemp.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisMonth.LowTemp.Desc, ThisMonth.LowTemp.Val, ThisMonth.LowTemp.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisMonth.LowTemp.Desc, ThisMonth.LowTemp.Val, ThisMonth.LowTemp.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisMonth.HighDewPoint.Desc, ThisMonth.HighDewPoint.Val, ThisMonth.HighDewPoint.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisMonth.HighDewPoint.Desc, ThisMonth.HighDewPoint.Val, ThisMonth.HighDewPoint.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisMonth.LowDewPoint.Desc, ThisMonth.LowDewPoint.Val, ThisMonth.LowDewPoint.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisMonth.LowDewPoint.Desc, ThisMonth.LowDewPoint.Val, ThisMonth.LowDewPoint.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisMonth.HighAppTemp.Desc, ThisMonth.HighAppTemp.Val, ThisMonth.HighAppTemp.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisMonth.HighAppTemp.Desc, ThisMonth.HighAppTemp.Val, ThisMonth.HighAppTemp.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisMonth.LowAppTemp.Desc, ThisMonth.LowAppTemp.Val, ThisMonth.LowAppTemp.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisMonth.LowAppTemp.Desc, ThisMonth.LowAppTemp.Val, ThisMonth.LowAppTemp.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisMonth.HighFeelsLike.Desc, ThisMonth.HighFeelsLike.Val, ThisMonth.HighFeelsLike.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisMonth.HighFeelsLike.Desc, ThisMonth.HighFeelsLike.Val, ThisMonth.HighFeelsLike.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisMonth.LowFeelsLike.Desc, ThisMonth.LowFeelsLike.Val, ThisMonth.LowFeelsLike.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisMonth.LowFeelsLike.Desc, ThisMonth.LowFeelsLike.Val, ThisMonth.LowFeelsLike.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); json.Append(monthyearjsonformat(ThisMonth.HighHumidex.Desc, ThisMonth.HighHumidex.Val, ThisMonth.HighHumidex.Ts, " ", cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisMonth.LowChill.Desc, ThisMonth.LowChill.Val, ThisMonth.LowChill.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisMonth.LowChill.Desc, ThisMonth.LowChill.Val, ThisMonth.LowChill.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisMonth.HighHeatIndex.Desc, ThisMonth.HighHeatIndex.Val, ThisMonth.HighHeatIndex.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisMonth.HighHeatIndex.Desc, ThisMonth.HighHeatIndex.Val, ThisMonth.HighHeatIndex.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisMonth.HighMinTemp.Desc, ThisMonth.HighMinTemp.Val, ThisMonth.HighMinTemp.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisMonth.HighMinTemp.Desc, ThisMonth.HighMinTemp.Val, ThisMonth.HighMinTemp.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisMonth.LowMaxTemp.Desc, ThisMonth.LowMaxTemp.Val, ThisMonth.LowMaxTemp.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisMonth.LowMaxTemp.Desc, ThisMonth.LowMaxTemp.Val, ThisMonth.LowMaxTemp.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisMonth.HighDailyTempRange.Desc, ThisMonth.HighDailyTempRange.Val, ThisMonth.HighDailyTempRange.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "D")); + json.Append(monthyearjsonformat(ThisMonth.HighDailyTempRange.Desc, ThisMonth.HighDailyTempRange.Val, ThisMonth.HighDailyTempRange.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "D")); json.Append(","); - json.Append(monthyearjsonformat(ThisMonth.LowDailyTempRange.Desc, ThisMonth.LowDailyTempRange.Val, ThisMonth.LowDailyTempRange.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "D")); + json.Append(monthyearjsonformat(ThisMonth.LowDailyTempRange.Desc, ThisMonth.LowDailyTempRange.Val, ThisMonth.LowDailyTempRange.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "D")); json.Append("]}"); return json.ToString(); } @@ -9451,9 +9451,9 @@ public string GetThisMonthPressRecords() { var json = new StringBuilder("{\"data\":[", 256); - json.Append(monthyearjsonformat(ThisMonth.HighPress.Desc, ThisMonth.HighPress.Val, ThisMonth.HighPress.Ts, cumulus.PressUnitText, cumulus.PressFormat, "f")); + json.Append(monthyearjsonformat(ThisMonth.HighPress.Desc, ThisMonth.HighPress.Val, ThisMonth.HighPress.Ts, cumulus.Units.PressText, cumulus.PressFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisMonth.LowPress.Desc, ThisMonth.LowPress.Val, ThisMonth.LowPress.Ts, cumulus.PressUnitText, cumulus.PressFormat, "f")); + json.Append(monthyearjsonformat(ThisMonth.LowPress.Desc, ThisMonth.LowPress.Val, ThisMonth.LowPress.Ts, cumulus.Units.PressText, cumulus.PressFormat, "f")); json.Append("]}"); return json.ToString(); } @@ -9462,11 +9462,11 @@ public string GetThisMonthWindRecords() { var json = new StringBuilder("{\"data\":[", 256); - json.Append(monthyearjsonformat(ThisMonth.HighGust.Desc, ThisMonth.HighGust.Val, ThisMonth.HighGust.Ts, cumulus.WindUnitText, cumulus.WindFormat, "f")); + json.Append(monthyearjsonformat(ThisMonth.HighGust.Desc, ThisMonth.HighGust.Val, ThisMonth.HighGust.Ts, cumulus.Units.WindText, cumulus.WindFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisMonth.HighWind.Desc, ThisMonth.HighWind.Val, ThisMonth.HighWind.Ts, cumulus.WindUnitText, cumulus.WindAvgFormat, "f")); + json.Append(monthyearjsonformat(ThisMonth.HighWind.Desc, ThisMonth.HighWind.Val, ThisMonth.HighWind.Ts, cumulus.Units.WindText, cumulus.WindAvgFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisMonth.HighWindRun.Desc, ThisMonth.HighWindRun.Val, ThisMonth.HighWindRun.Ts, cumulus.WindRunUnitText, cumulus.WindRunFormat, "D")); + json.Append(monthyearjsonformat(ThisMonth.HighWindRun.Desc, ThisMonth.HighWindRun.Val, ThisMonth.HighWindRun.Ts, cumulus.Units.WindRunText, cumulus.WindRunFormat, "D")); json.Append("]}"); return json.ToString(); } @@ -9475,13 +9475,13 @@ public string GetThisMonthRainRecords() { var json = new StringBuilder("{\"data\":[", 512); - json.Append(monthyearjsonformat(ThisMonth.HighRainRate.Desc, ThisMonth.HighRainRate.Val, ThisMonth.HighRainRate.Ts, cumulus.RainUnitText + "/hr", cumulus.RainFormat, "f")); + json.Append(monthyearjsonformat(ThisMonth.HighRainRate.Desc, ThisMonth.HighRainRate.Val, ThisMonth.HighRainRate.Ts, cumulus.Units.RainText + "/hr", cumulus.RainFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisMonth.HourlyRain.Desc, ThisMonth.HourlyRain.Val, ThisMonth.HourlyRain.Ts, cumulus.RainUnitText, cumulus.RainFormat, "f")); + json.Append(monthyearjsonformat(ThisMonth.HourlyRain.Desc, ThisMonth.HourlyRain.Val, ThisMonth.HourlyRain.Ts, cumulus.Units.RainText, cumulus.RainFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisMonth.DailyRain.Desc, ThisMonth.DailyRain.Val, ThisMonth.DailyRain.Ts, cumulus.RainUnitText, cumulus.RainFormat, "D")); + json.Append(monthyearjsonformat(ThisMonth.DailyRain.Desc, ThisMonth.DailyRain.Val, ThisMonth.DailyRain.Ts, cumulus.Units.RainText, cumulus.RainFormat, "D")); json.Append(","); - //json.Append(monthyearjsonformat(ThisMonth.WetMonth.Desc, month, cumulus.RainUnitText, cumulus.RainFormat, "Y")); + //json.Append(monthyearjsonformat(ThisMonth.WetMonth.Desc, month, cumulus.Units.RainText, cumulus.RainFormat, "Y")); //json.Append(","); json.Append(monthyearjsonformat(ThisMonth.LongestDryPeriod.Desc, ThisMonth.LongestDryPeriod.Val, ThisMonth.LongestDryPeriod.Ts, "days", "f0", "D")); json.Append(","); @@ -9494,35 +9494,35 @@ public string GetThisYearTempRecords() { var json = new StringBuilder("{\"data\":[", 1024); - json.Append(monthyearjsonformat(ThisYear.HighTemp.Desc, ThisYear.HighTemp.Val, ThisYear.HighTemp.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisYear.HighTemp.Desc, ThisYear.HighTemp.Val, ThisYear.HighTemp.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisYear.LowTemp.Desc, ThisYear.LowTemp.Val, ThisYear.LowTemp.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisYear.LowTemp.Desc, ThisYear.LowTemp.Val, ThisYear.LowTemp.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisYear.HighDewPoint.Desc, ThisYear.HighDewPoint.Val, ThisYear.HighDewPoint.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisYear.HighDewPoint.Desc, ThisYear.HighDewPoint.Val, ThisYear.HighDewPoint.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisYear.LowDewPoint.Desc, ThisYear.LowDewPoint.Val, ThisYear.LowDewPoint.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisYear.LowDewPoint.Desc, ThisYear.LowDewPoint.Val, ThisYear.LowDewPoint.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisYear.HighAppTemp.Desc, ThisYear.HighAppTemp.Val, ThisYear.HighAppTemp.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisYear.HighAppTemp.Desc, ThisYear.HighAppTemp.Val, ThisYear.HighAppTemp.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisYear.LowAppTemp.Desc, ThisYear.LowAppTemp.Val, ThisYear.LowAppTemp.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisYear.LowAppTemp.Desc, ThisYear.LowAppTemp.Val, ThisYear.LowAppTemp.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisYear.HighFeelsLike.Desc, ThisYear.HighFeelsLike.Val, ThisYear.HighFeelsLike.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisYear.HighFeelsLike.Desc, ThisYear.HighFeelsLike.Val, ThisYear.HighFeelsLike.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisYear.LowFeelsLike.Desc, ThisYear.LowFeelsLike.Val, ThisYear.LowFeelsLike.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisYear.LowFeelsLike.Desc, ThisYear.LowFeelsLike.Val, ThisYear.LowFeelsLike.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); json.Append(monthyearjsonformat(ThisYear.HighHumidex.Desc, ThisYear.HighHumidex.Val, ThisYear.HighHumidex.Ts, " ", cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisYear.LowChill.Desc, ThisYear.LowChill.Val, ThisYear.LowChill.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisYear.LowChill.Desc, ThisYear.LowChill.Val, ThisYear.LowChill.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisYear.HighHeatIndex.Desc, ThisYear.HighHeatIndex.Val, ThisYear.HighHeatIndex.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisYear.HighHeatIndex.Desc, ThisYear.HighHeatIndex.Val, ThisYear.HighHeatIndex.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisYear.HighMinTemp.Desc, ThisYear.HighMinTemp.Val, ThisYear.HighMinTemp.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisYear.HighMinTemp.Desc, ThisYear.HighMinTemp.Val, ThisYear.HighMinTemp.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisYear.LowMaxTemp.Desc, ThisYear.LowMaxTemp.Val, ThisYear.LowMaxTemp.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "f")); + json.Append(monthyearjsonformat(ThisYear.LowMaxTemp.Desc, ThisYear.LowMaxTemp.Val, ThisYear.LowMaxTemp.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisYear.HighDailyTempRange.Desc, ThisYear.HighDailyTempRange.Val, ThisYear.HighDailyTempRange.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "D")); + json.Append(monthyearjsonformat(ThisYear.HighDailyTempRange.Desc, ThisYear.HighDailyTempRange.Val, ThisYear.HighDailyTempRange.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "D")); json.Append(","); - json.Append(monthyearjsonformat(ThisYear.LowDailyTempRange.Desc, ThisYear.LowDailyTempRange.Val, ThisYear.LowDailyTempRange.Ts, "°" + cumulus.TempUnitText[1].ToString(), cumulus.TempFormat, "D")); + json.Append(monthyearjsonformat(ThisYear.LowDailyTempRange.Desc, ThisYear.LowDailyTempRange.Val, ThisYear.LowDailyTempRange.Ts, "°" + cumulus.Units.TempText[1].ToString(), cumulus.TempFormat, "D")); json.Append("]}"); return json.ToString(); } @@ -9542,9 +9542,9 @@ public string GetThisYearPressRecords() { var json = new StringBuilder("{\"data\":[", 256); - json.Append(monthyearjsonformat(ThisYear.HighPress.Desc, ThisYear.HighPress.Val, ThisYear.HighPress.Ts, cumulus.PressUnitText, cumulus.PressFormat, "f")); + json.Append(monthyearjsonformat(ThisYear.HighPress.Desc, ThisYear.HighPress.Val, ThisYear.HighPress.Ts, cumulus.Units.PressText, cumulus.PressFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisYear.LowPress.Desc, ThisYear.LowPress.Val, ThisYear.LowPress.Ts, cumulus.PressUnitText, cumulus.PressFormat, "f")); + json.Append(monthyearjsonformat(ThisYear.LowPress.Desc, ThisYear.LowPress.Val, ThisYear.LowPress.Ts, cumulus.Units.PressText, cumulus.PressFormat, "f")); json.Append("]}"); return json.ToString(); } @@ -9553,11 +9553,11 @@ public string GetThisYearWindRecords() { var json = new StringBuilder("{\"data\":[", 256); - json.Append(monthyearjsonformat(ThisYear.HighGust.Desc, ThisYear.HighGust.Val, ThisYear.HighGust.Ts, cumulus.WindUnitText, cumulus.WindFormat, "f")); + json.Append(monthyearjsonformat(ThisYear.HighGust.Desc, ThisYear.HighGust.Val, ThisYear.HighGust.Ts, cumulus.Units.WindText, cumulus.WindFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisYear.HighWind.Desc, ThisYear.HighWind.Val, ThisYear.HighWind.Ts, cumulus.WindUnitText, cumulus.WindAvgFormat, "f")); + json.Append(monthyearjsonformat(ThisYear.HighWind.Desc, ThisYear.HighWind.Val, ThisYear.HighWind.Ts, cumulus.Units.WindText, cumulus.WindAvgFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisYear.HighWindRun.Desc, ThisYear.HighWindRun.Val, ThisYear.HighWindRun.Ts, cumulus.WindRunUnitText, cumulus.WindRunFormat, "D")); + json.Append(monthyearjsonformat(ThisYear.HighWindRun.Desc, ThisYear.HighWindRun.Val, ThisYear.HighWindRun.Ts, cumulus.Units.WindRunText, cumulus.WindRunFormat, "D")); json.Append("]}"); return json.ToString(); } @@ -9566,13 +9566,13 @@ public string GetThisYearRainRecords() { var json = new StringBuilder("{\"data\":[", 512); - json.Append(monthyearjsonformat(ThisYear.HighRainRate.Desc, ThisYear.HighRainRate.Val, ThisYear.HighRainRate.Ts, cumulus.RainUnitText + "/hr", cumulus.RainFormat, "f")); + json.Append(monthyearjsonformat(ThisYear.HighRainRate.Desc, ThisYear.HighRainRate.Val, ThisYear.HighRainRate.Ts, cumulus.Units.RainText + "/hr", cumulus.RainFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisYear.HourlyRain.Desc, ThisYear.HourlyRain.Val, ThisYear.HourlyRain.Ts, cumulus.RainUnitText, cumulus.RainFormat, "f")); + json.Append(monthyearjsonformat(ThisYear.HourlyRain.Desc, ThisYear.HourlyRain.Val, ThisYear.HourlyRain.Ts, cumulus.Units.RainText, cumulus.RainFormat, "f")); json.Append(","); - json.Append(monthyearjsonformat(ThisYear.DailyRain.Desc, ThisYear.DailyRain.Val, ThisYear.DailyRain.Ts, cumulus.RainUnitText, cumulus.RainFormat, "D")); + json.Append(monthyearjsonformat(ThisYear.DailyRain.Desc, ThisYear.DailyRain.Val, ThisYear.DailyRain.Ts, cumulus.Units.RainText, cumulus.RainFormat, "D")); json.Append(","); - json.Append(monthyearjsonformat(ThisYear.MonthlyRain.Desc, ThisYear.MonthlyRain.Val, ThisYear.MonthlyRain.Ts, cumulus.RainUnitText, cumulus.RainFormat, "Y")); + json.Append(monthyearjsonformat(ThisYear.MonthlyRain.Desc, ThisYear.MonthlyRain.Val, ThisYear.MonthlyRain.Ts, cumulus.Units.RainText, cumulus.RainFormat, "Y")); json.Append(","); json.Append(monthyearjsonformat(ThisYear.LongestDryPeriod.Desc, ThisYear.LongestDryPeriod.Val, ThisYear.LongestDryPeriod.Ts, "days", "f0", "D")); json.Append(","); @@ -9592,7 +9592,7 @@ public string GetExtraTemp() json.Append("\",\""); json.Append(ExtraTemp[sensor].ToString(cumulus.TempFormat)); json.Append("\",\"°"); - json.Append(cumulus.TempUnitText[1].ToString()); + json.Append(cumulus.Units.TempText[1].ToString()); json.Append("\"]"); if (sensor < 10) @@ -9616,7 +9616,7 @@ public string GetUserTemp() json.Append("\",\""); json.Append(UserTemp[sensor].ToString(cumulus.TempFormat)); json.Append("\",\"°"); - json.Append(cumulus.TempUnitText[1].ToString()); + json.Append(cumulus.Units.TempText[1].ToString()); json.Append("\"]"); if (sensor < 8) @@ -9662,7 +9662,7 @@ public string GetExtraDew() json.Append("\",\""); json.Append(ExtraDewPoint[sensor].ToString(cumulus.TempFormat)); json.Append("\",\"°"); - json.Append(cumulus.TempUnitText[1].ToString()); + json.Append(cumulus.Units.TempText[1].ToString()); json.Append("\"]"); if (sensor < 10) @@ -9679,22 +9679,22 @@ public string GetSoilTemp() { var json = new StringBuilder("{\"data\":[", 2048); - json.Append($"[\"{cumulus.SoilTempCaptions[1]}\",\"{SoilTemp1.ToString(cumulus.TempFormat)}\",\"°{cumulus.TempUnitText[1]}\"],"); - json.Append($"[\"{cumulus.SoilTempCaptions[2]}\",\"{SoilTemp2.ToString(cumulus.TempFormat)}\",\"°{cumulus.TempUnitText[1]}\"],"); - json.Append($"[\"{cumulus.SoilTempCaptions[3]}\",\"{SoilTemp3.ToString(cumulus.TempFormat)}\",\"°{cumulus.TempUnitText[1]}\"],"); - json.Append($"[\"{cumulus.SoilTempCaptions[4]}\",\"{SoilTemp4.ToString(cumulus.TempFormat)}\",\"°{cumulus.TempUnitText[1]}\"],"); - json.Append($"[\"{cumulus.SoilTempCaptions[5]}\",\"{SoilTemp5.ToString(cumulus.TempFormat)}\",\"°{cumulus.TempUnitText[1]}\"],"); - json.Append($"[\"{cumulus.SoilTempCaptions[6]}\",\"{SoilTemp6.ToString(cumulus.TempFormat)}\",\"°{cumulus.TempUnitText[1]}\"],"); - json.Append($"[\"{cumulus.SoilTempCaptions[7]}\",\"{SoilTemp7.ToString(cumulus.TempFormat)}\",\"°{cumulus.TempUnitText[1]}\"],"); - json.Append($"[\"{cumulus.SoilTempCaptions[8]}\",\"{SoilTemp8.ToString(cumulus.TempFormat)}\",\"°{cumulus.TempUnitText[1]}\"],"); - json.Append($"[\"{cumulus.SoilTempCaptions[9]}\",\"{SoilTemp9.ToString(cumulus.TempFormat)}\",\"°{cumulus.TempUnitText[1]}\"],"); - json.Append($"[\"{cumulus.SoilTempCaptions[10]}\",\"{SoilTemp10.ToString(cumulus.TempFormat)}\",\"°{cumulus.TempUnitText[1]}\"],"); - json.Append($"[\"{cumulus.SoilTempCaptions[11]}\",\"{SoilTemp11.ToString(cumulus.TempFormat)}\",\"°{cumulus.TempUnitText[1]}\"],"); - json.Append($"[\"{cumulus.SoilTempCaptions[12]}\",\"{SoilTemp12.ToString(cumulus.TempFormat)}\",\"°{cumulus.TempUnitText[1]}\"],"); - json.Append($"[\"{cumulus.SoilTempCaptions[13]}\",\"{SoilTemp13.ToString(cumulus.TempFormat)}\",\"°{cumulus.TempUnitText[1]}\"],"); - json.Append($"[\"{cumulus.SoilTempCaptions[14]}\",\"{SoilTemp14.ToString(cumulus.TempFormat)}\",\"°{cumulus.TempUnitText[1]}\"],"); - json.Append($"[\"{cumulus.SoilTempCaptions[15]}\",\"{SoilTemp15.ToString(cumulus.TempFormat)}\",\"°{cumulus.TempUnitText[1]}\"],"); - json.Append($"[\"{cumulus.SoilTempCaptions[16]}\",\"{SoilTemp16.ToString(cumulus.TempFormat)}\",\"°{cumulus.TempUnitText[1]}\"]"); + json.Append($"[\"{cumulus.SoilTempCaptions[1]}\",\"{SoilTemp1.ToString(cumulus.TempFormat)}\",\"°{cumulus.Units.TempText[1]}\"],"); + json.Append($"[\"{cumulus.SoilTempCaptions[2]}\",\"{SoilTemp2.ToString(cumulus.TempFormat)}\",\"°{cumulus.Units.TempText[1]}\"],"); + json.Append($"[\"{cumulus.SoilTempCaptions[3]}\",\"{SoilTemp3.ToString(cumulus.TempFormat)}\",\"°{cumulus.Units.TempText[1]}\"],"); + json.Append($"[\"{cumulus.SoilTempCaptions[4]}\",\"{SoilTemp4.ToString(cumulus.TempFormat)}\",\"°{cumulus.Units.TempText[1]}\"],"); + json.Append($"[\"{cumulus.SoilTempCaptions[5]}\",\"{SoilTemp5.ToString(cumulus.TempFormat)}\",\"°{cumulus.Units.TempText[1]}\"],"); + json.Append($"[\"{cumulus.SoilTempCaptions[6]}\",\"{SoilTemp6.ToString(cumulus.TempFormat)}\",\"°{cumulus.Units.TempText[1]}\"],"); + json.Append($"[\"{cumulus.SoilTempCaptions[7]}\",\"{SoilTemp7.ToString(cumulus.TempFormat)}\",\"°{cumulus.Units.TempText[1]}\"],"); + json.Append($"[\"{cumulus.SoilTempCaptions[8]}\",\"{SoilTemp8.ToString(cumulus.TempFormat)}\",\"°{cumulus.Units.TempText[1]}\"],"); + json.Append($"[\"{cumulus.SoilTempCaptions[9]}\",\"{SoilTemp9.ToString(cumulus.TempFormat)}\",\"°{cumulus.Units.TempText[1]}\"],"); + json.Append($"[\"{cumulus.SoilTempCaptions[10]}\",\"{SoilTemp10.ToString(cumulus.TempFormat)}\",\"°{cumulus.Units.TempText[1]}\"],"); + json.Append($"[\"{cumulus.SoilTempCaptions[11]}\",\"{SoilTemp11.ToString(cumulus.TempFormat)}\",\"°{cumulus.Units.TempText[1]}\"],"); + json.Append($"[\"{cumulus.SoilTempCaptions[12]}\",\"{SoilTemp12.ToString(cumulus.TempFormat)}\",\"°{cumulus.Units.TempText[1]}\"],"); + json.Append($"[\"{cumulus.SoilTempCaptions[13]}\",\"{SoilTemp13.ToString(cumulus.TempFormat)}\",\"°{cumulus.Units.TempText[1]}\"],"); + json.Append($"[\"{cumulus.SoilTempCaptions[14]}\",\"{SoilTemp14.ToString(cumulus.TempFormat)}\",\"°{cumulus.Units.TempText[1]}\"],"); + json.Append($"[\"{cumulus.SoilTempCaptions[15]}\",\"{SoilTemp15.ToString(cumulus.TempFormat)}\",\"°{cumulus.Units.TempText[1]}\"],"); + json.Append($"[\"{cumulus.SoilTempCaptions[16]}\",\"{SoilTemp16.ToString(cumulus.TempFormat)}\",\"°{cumulus.Units.TempText[1]}\"]"); json.Append("]}"); return json.ToString(); } @@ -9757,7 +9757,7 @@ public string GetLightning() { var json = new StringBuilder("{\"data\":[", 256); - json.Append($"[\"Distance to last strike\",\"{LightningDistance.ToString(cumulus.WindRunFormat)}\",\"{cumulus.WindRunUnitText}\"],"); + json.Append($"[\"Distance to last strike\",\"{LightningDistance.ToString(cumulus.WindRunFormat)}\",\"{cumulus.Units.WindRunText}\"],"); json.Append($"[\"Time of last strike\",\"{LightningTime}\",\"\"],"); json.Append($"[\"Number of strikes today\",\"{LightningStrikesToday}\",\"\"]"); json.Append("]}"); @@ -9768,8 +9768,8 @@ public string GetLeaf() { var json = new StringBuilder("{\"data\":[", 256); - json.Append($"[\"{cumulus.LeafCaptions[1]}\",\"{LeafTemp1.ToString(cumulus.TempFormat)}\",\"°{cumulus.TempUnitText[1]}\"],"); - json.Append($"[\"{cumulus.LeafCaptions[2]}\",\"{LeafTemp2.ToString(cumulus.TempFormat)}\",\"°{cumulus.TempUnitText[1]}\"],"); + json.Append($"[\"{cumulus.LeafCaptions[1]}\",\"{LeafTemp1.ToString(cumulus.TempFormat)}\",\"°{cumulus.Units.TempText[1]}\"],"); + json.Append($"[\"{cumulus.LeafCaptions[2]}\",\"{LeafTemp2.ToString(cumulus.TempFormat)}\",\"°{cumulus.Units.TempText[1]}\"],"); json.Append($"[\"{cumulus.LeafCaptions[3]}\",\"{LeafWetness1}\",\" \"],"); json.Append($"[\"{cumulus.LeafCaptions[4]}\",\"{LeafWetness2}\",\" \"]"); json.Append("]}"); @@ -9780,10 +9780,10 @@ public string GetLeaf4() { var json = new StringBuilder("{\"data\":[", 256); - json.Append($"[\"{cumulus.LeafCaptions[1]}\",\"{LeafTemp1.ToString(cumulus.TempFormat)} °{cumulus.TempUnitText[1]}\",\"{LeafWetness1}\"],"); - json.Append($"[\"{cumulus.LeafCaptions[2]}\",\"{LeafTemp2.ToString(cumulus.TempFormat)} °{cumulus.TempUnitText[1]}\",\"{LeafWetness2}\"],"); - json.Append($"[\"{cumulus.LeafCaptions[3]}\",\"{LeafTemp3.ToString(cumulus.TempFormat)} °{cumulus.TempUnitText[1]}\",\"{LeafWetness3}\"],"); - json.Append($"[\"{cumulus.LeafCaptions[4]}\",\"{LeafTemp4.ToString(cumulus.TempFormat)} °{cumulus.TempUnitText[1]}\",\"{LeafWetness4}\"]"); + json.Append($"[\"{cumulus.LeafCaptions[1]}\",\"{LeafTemp1.ToString(cumulus.TempFormat)} °{cumulus.Units.TempText[1]}\",\"{LeafWetness1}\"],"); + json.Append($"[\"{cumulus.LeafCaptions[2]}\",\"{LeafTemp2.ToString(cumulus.TempFormat)} °{cumulus.Units.TempText[1]}\",\"{LeafWetness2}\"],"); + json.Append($"[\"{cumulus.LeafCaptions[3]}\",\"{LeafTemp3.ToString(cumulus.TempFormat)} °{cumulus.Units.TempText[1]}\",\"{LeafWetness3}\"],"); + json.Append($"[\"{cumulus.LeafCaptions[4]}\",\"{LeafTemp4.ToString(cumulus.TempFormat)} °{cumulus.Units.TempText[1]}\",\"{LeafWetness4}\"]"); json.Append("]}"); return json.ToString(); } @@ -9905,7 +9905,7 @@ public string GetTodayYestTemp() var json = new StringBuilder("{\"data\":[", 2048); var sepStr = "\",\""; var closeStr = "\"],"; - var tempUnitStr = " °" + cumulus.TempUnitText[1].ToString() + sepStr; + var tempUnitStr = " °" + cumulus.Units.TempText[1].ToString() + sepStr; json.Append("[\"High Temperature\",\""); json.Append(HiLoToday.HighTemp.ToString(cumulus.TempFormat)); @@ -10062,7 +10062,7 @@ public string GetTodayYestRain() { var json = new StringBuilder("{\"data\":[", 512); var sepStr = "\",\""; - var unitStr = " " + cumulus.RainUnitText; + var unitStr = " " + cumulus.Units.RainText; json.Append("[\"Total Rain\",\""); json.Append(RainToday.ToString(cumulus.RainFormat)); @@ -10111,36 +10111,36 @@ public string GetTodayYestWind() json.Append("[\"Highest Gust\",\""); json.Append(HiLoToday.HighGust.ToString(cumulus.WindFormat)); - json.Append(" " + cumulus.WindUnitText); + json.Append(" " + cumulus.Units.WindText); json.Append(sepStr); json.Append(HiLoToday.HighGustTime.ToShortTimeString()); json.Append(sepStr); json.Append(HiLoYest.HighGust.ToString(cumulus.WindFormat)); - json.Append(" " + cumulus.WindUnitText); + json.Append(" " + cumulus.Units.WindText); json.Append(sepStr); json.Append(HiLoYest.HighGustTime.ToShortTimeString()); json.Append("\"],"); json.Append("[\"Highest Speed\",\""); json.Append(HiLoToday.HighWind.ToString(cumulus.WindAvgFormat)); - json.Append(" " + cumulus.WindUnitText); + json.Append(" " + cumulus.Units.WindText); json.Append(sepStr); json.Append(HiLoToday.HighWindTime.ToShortTimeString()); json.Append(sepStr); json.Append(HiLoYest.HighWind.ToString(cumulus.WindAvgFormat)); - json.Append(" " + cumulus.WindUnitText); + json.Append(" " + cumulus.Units.WindText); json.Append(sepStr); json.Append(HiLoYest.HighWindTime.ToShortTimeString()); json.Append("\"],"); json.Append("[\"Wind Run\",\""); json.Append(WindRunToday.ToString(cumulus.WindRunFormat)); - json.Append(" " + cumulus.WindRunUnitText); + json.Append(" " + cumulus.Units.WindRunText); json.Append(sepStr); json.Append(" "); json.Append(sepStr); json.Append(YesterdayWindRun.ToString(cumulus.WindRunFormat)); - json.Append(" " + cumulus.WindRunUnitText); + json.Append(" " + cumulus.Units.WindRunText); json.Append(sepStr); json.Append(" "); json.Append("\"],"); @@ -10165,7 +10165,7 @@ public string GetTodayYestPressure() { var json = new StringBuilder("{\"data\":[", 512); var sepStr = "\",\""; - var unitStr = " " + cumulus.PressUnitText; + var unitStr = " " + cumulus.Units.PressText; json.Append("[\"High Pressure\",\""); json.Append(HiLoToday.HighPress.ToString(cumulus.PressFormat)); @@ -10439,17 +10439,17 @@ public string GetLogfile(string date, string draw, int start, int length, bool e public string GetUnits() { - return $"{{\"temp\":\"{cumulus.TempUnitText[1]}\",\"wind\":\"{cumulus.WindUnitText}\",\"rain\":\"{cumulus.RainUnitText}\",\"press\":\"{cumulus.PressUnitText}\"}}"; + return $"{{\"temp\":\"{cumulus.Units.TempText[1]}\",\"wind\":\"{cumulus.Units.WindText}\",\"rain\":\"{cumulus.Units.RainText}\",\"press\":\"{cumulus.Units.PressText}\"}}"; } public string GetGraphConfig() { var json = new StringBuilder(200); json.Append("{"); - json.Append($"\"temp\":{{\"units\":\"{cumulus.TempUnitText[1]}\",\"decimals\":{cumulus.TempDPlaces}}},"); - json.Append($"\"wind\":{{\"units\":\"{cumulus.WindUnitText}\",\"decimals\":{cumulus.WindAvgDPlaces},\"rununits\":\"{cumulus.WindRunUnitText}\"}},"); - json.Append($"\"rain\":{{\"units\":\"{cumulus.RainUnitText}\",\"decimals\":{cumulus.RainDPlaces}}},"); - json.Append($"\"press\":{{\"units\":\"{cumulus.PressUnitText}\",\"decimals\":{cumulus.PressDPlaces}}},"); + json.Append($"\"temp\":{{\"units\":\"{cumulus.Units.TempText[1]}\",\"decimals\":{cumulus.TempDPlaces}}},"); + json.Append($"\"wind\":{{\"units\":\"{cumulus.Units.WindText}\",\"decimals\":{cumulus.WindAvgDPlaces},\"rununits\":\"{cumulus.Units.WindRunText}\"}},"); + json.Append($"\"rain\":{{\"units\":\"{cumulus.Units.RainText}\",\"decimals\":{cumulus.RainDPlaces}}},"); + json.Append($"\"press\":{{\"units\":\"{cumulus.Units.PressText}\",\"decimals\":{cumulus.PressDPlaces}}},"); json.Append($"\"hum\":{{\"decimals\":{cumulus.HumDPlaces}}},"); json.Append($"\"uv\":{{\"decimals\":{cumulus.UVDPlaces}}}"); json.Append("}"); @@ -11145,10 +11145,10 @@ internal string GetCurrentData() var data = new DataStruct(cumulus, OutdoorTemperature, OutdoorHumidity, TempTotalToday / tempsamplestoday, IndoorTemperature, OutdoorDewpoint, WindChill, IndoorHumidity, Pressure, WindLatest, WindAverage, RecentMaxGust, WindRunToday, Bearing, AvgBearing, RainToday, RainYesterday, RainMonth, RainYear, RainRate, RainLastHour, HeatIndex, Humidex, ApparentTemperature, temptrendval, presstrendval, HiLoToday.HighGust, HiLoToday.HighGustTime.ToString("HH:mm"), HiLoToday.HighWind, - HiLoToday.HighGustBearing, cumulus.WindUnitText, BearingRangeFrom10, BearingRangeTo10, windRoseData.ToString(), HiLoToday.HighTemp, HiLoToday.LowTemp, + HiLoToday.HighGustBearing, cumulus.Units.WindText, BearingRangeFrom10, BearingRangeTo10, windRoseData.ToString(), HiLoToday.HighTemp, HiLoToday.LowTemp, HiLoToday.HighTempTime.ToString("HH:mm"), HiLoToday.LowTempTime.ToString("HH:mm"), HiLoToday.HighPress, HiLoToday.LowPress, HiLoToday.HighPressTime.ToString("HH:mm"), HiLoToday.LowPressTime.ToString("HH:mm"), HiLoToday.HighRainRate, HiLoToday.HighRainRateTime.ToString("HH:mm"), HiLoToday.HighHumidity, HiLoToday.LowHumidity, - HiLoToday.HighHumidityTime.ToString("HH:mm"), HiLoToday.LowHumidityTime.ToString("HH:mm"), cumulus.PressUnitText, cumulus.TempUnitText, cumulus.RainUnitText, + HiLoToday.HighHumidityTime.ToString("HH:mm"), HiLoToday.LowHumidityTime.ToString("HH:mm"), cumulus.Units.PressText, cumulus.Units.TempText, cumulus.Units.RainText, HiLoToday.HighDewPoint, HiLoToday.LowDewPoint, HiLoToday.HighDewPointTime.ToString("HH:mm"), HiLoToday.LowDewPointTime.ToString("HH:mm"), HiLoToday.LowWindChill, HiLoToday.LowWindChillTime.ToString("HH:mm"), (int)SolarRad, (int)HiLoToday.HighSolar, HiLoToday.HighSolarTime.ToString("HH:mm"), UV, HiLoToday.HighUv, HiLoToday.HighUvTime.ToString("HH:mm"), forecaststr, getTimeString(cumulus.SunRiseTime), getTimeString(cumulus.SunSetTime), @@ -11419,7 +11419,7 @@ private string APRSLon(Cumulus cumulus) } /// - /// input is in WindUnit units, convert to mph for APRS + /// input is in Units.Wind units, convert to mph for APRS /// and return 3 digits /// /// @@ -11431,7 +11431,7 @@ private string APRSwind(double wind) } /// - /// input is in PressUnit units, convert to tenths of mb for APRS + /// input is in Units.Press units, convert to tenths of mb for APRS /// return 5 digit string /// /// diff --git a/CumulusMX/webtags.cs b/CumulusMX/webtags.cs index 6b16fffa..a4bbaf79 100644 --- a/CumulusMX/webtags.cs +++ b/CumulusMX/webtags.cs @@ -2882,32 +2882,32 @@ private string Tagwebcam(Dictionary tagParams) private string Tagtempunit(Dictionary tagParams) { - return EncodeForWeb(cumulus.TempUnitText); + return EncodeForWeb(cumulus.Units.TempText); } private string Tagtempunitnodeg(Dictionary tagParams) { - return EncodeForWeb(cumulus.TempUnitText.Substring(1,1)); + return EncodeForWeb(cumulus.Units.TempText.Substring(1,1)); } private string Tagwindunit(Dictionary tagParams) { - return cumulus.WindUnitText; + return cumulus.Units.WindText; } private string Tagwindrununit(Dictionary tagParams) { - return cumulus.WindRunUnitText; + return cumulus.Units.WindRunText; } private string Tagpressunit(Dictionary tagParams) { - return cumulus.PressUnitText; + return cumulus.Units.PressText; } private string Tagrainunit(Dictionary tagParams) { - return cumulus.RainUnitText; + return cumulus.Units.RainText; } private string Taginterval(Dictionary tagParams) @@ -4643,8 +4643,15 @@ private string TagSystemUpTime(Dictionary tagParams) double upTime = 0; if (cumulus.Platform.Substring(0, 3) == "Win") { - cumulus.UpTime.NextValue(); - upTime = cumulus.UpTime.NextValue(); + try + { + cumulus.UpTime.NextValue(); + upTime = cumulus.UpTime.NextValue(); + } + catch + { + // do nothing, already set to zero + } } else if (File.Exists(@"/proc/uptime")) { diff --git a/Updates.txt b/Updates.txt index 030bcc37..8ae33cef 100644 --- a/Updates.txt +++ b/Updates.txt @@ -1,3 +1,14 @@ +3.10.0 - b3108 +—————————————— +- Change: The following configuration items are now available via the settings screens + Davis + UseDavisLoop2 + DavisInitWaitTime + DavisIPResponseTime + + + + 3.9.7 - b3107 ————————————— - Fix: Unhandled exception in ProcessTemplateFile if cumulus cannot write to the output file From f3411a9acbae40dde5cf3f87c4d7aee5a14c8657 Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Thu, 4 Feb 2021 16:37:54 +0000 Subject: [PATCH 02/12] Catch System uptime counter errors, change clock sync time --- CumulusMX/Cumulus.cs | 14 +++++++++++--- CumulusMX/DavisStation.cs | 2 +- CumulusMX/ImetStation.cs | 2 +- CumulusMX/NOAA.cs | 4 ++-- Updates.txt | 9 +++++++++ 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index 63cdeac2..d559487d 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -939,8 +939,16 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) // determine system uptime based on OS if (Platform.Substring(0, 3) == "Win") { - // Windows enable the performance counter method - UpTime = new PerformanceCounter("System", "System Up Time"); + try + { + // Windows enable the performance counter method + UpTime = new PerformanceCounter("System", "System Up Time"); + } + catch (Exception e) + { + LogMessage("Error: Unable to acces the System Up Time performance counter. System up time will not be available"); + LogDebugMessage($"Error: {e}"); + } } LogMessage("Current culture: " + CultureInfo.CurrentCulture.DisplayName); @@ -1089,7 +1097,7 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) { // Check uptime double ts = 0; - if (Platform.Substring(0, 3) == "Win") + if (Platform.Substring(0, 3) == "Win" && UpTime != null) { UpTime.NextValue(); ts = UpTime.NextValue(); diff --git a/CumulusMX/DavisStation.cs b/CumulusMX/DavisStation.cs index 97c7f26a..223f14b4 100644 --- a/CumulusMX/DavisStation.cs +++ b/CumulusMX/DavisStation.cs @@ -1222,7 +1222,7 @@ private void GetAndProcessLoopData(int number) if (min != previousMinuteSetClock) { previousMinuteSetClock = min; - if (cumulus.StationOptions.SyncTime && DateTime.Now.Hour == cumulus.ClockSettingHour && min == 0) + if (cumulus.StationOptions.SyncTime && DateTime.Now.Hour == cumulus.ClockSettingHour && min == 2) { // set the console clock clockSetNeeded = true; diff --git a/CumulusMX/ImetStation.cs b/CumulusMX/ImetStation.cs index f4f6b889..b84ae303 100644 --- a/CumulusMX/ImetStation.cs +++ b/CumulusMX/ImetStation.cs @@ -873,7 +873,7 @@ private void ImetGetData() { previousminute = min; - if (cumulus.StationOptions.SyncTime && (h == cumulus.ClockSettingHour) && (min == 0)) + if (cumulus.StationOptions.SyncTime && (h == cumulus.ClockSettingHour) && (min == 2)) { // It's 0400, set the station clock SetStationClock(); diff --git a/CumulusMX/NOAA.cs b/CumulusMX/NOAA.cs index 6b5d4988..674ef04e 100644 --- a/CumulusMX/NOAA.cs +++ b/CumulusMX/NOAA.cs @@ -967,7 +967,7 @@ public List CreateYearlyReport(DateTime thedate) } else { - repLine.Append(string.Format("{0,6}", (MonthList[month].meantemp - cumulus.NOAATempNorms[month]).ToString(cumulus.TempFormat, culture))); + repLine.Append(string.Format(culture, "{0,6:F1}", (MonthList[month].meantemp - cumulus.NOAATempNorms[month]))); totalnormtemp += cumulus.NOAATempNorms[month]; normtempsamples++; } @@ -1021,7 +1021,7 @@ public List CreateYearlyReport(DateTime thedate) repLine.Append(" 0.0"); else { - repLine.Append(string.Format("{0,6}", (meantemp - (totalnormtemp/normtempsamples)).ToString(cumulus.TempFormat, culture))); + repLine.Append(string.Format(culture, "{0,6F1}", (meantemp - (totalnormtemp/normtempsamples)))); } repLine.Append(string.Format(culture, "{0,6:D}{1,6:D}", (int) (totalheating), (int) (totalcooling))); if (maxtempmonth == 0) diff --git a/Updates.txt b/Updates.txt index 030bcc37..bcf2b2a5 100644 --- a/Updates.txt +++ b/Updates.txt @@ -1,3 +1,12 @@ +3.9.8 - b3108 +————————————— +- Fix: Catch error creating System Uptime counter on Windows + +- Change: Creation of the wxnow.txt file is now disabled by default for new installs +- Change: Clock sync (Davis VP2 & Instromet) now occurs at 2 minutes past the hour selected + + + 3.9.7 - b3107 ————————————— - Fix: Unhandled exception in ProcessTemplateFile if cumulus cannot write to the output file From c6b6a3d5a85641f1a5653bca828ed574adef2631 Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Fri, 5 Feb 2021 09:30:16 +0000 Subject: [PATCH 03/12] Add FineOffset Vid/Pid to setttings --- CumulusMX/Cumulus.cs | 24 +++++++++++++----------- CumulusMX/FOStation.cs | 4 ++-- CumulusMX/Properties/AssemblyInfo.cs | 6 +++--- CumulusMX/StationSettings.cs | 24 ++++++++++++++++++++---- Updates.txt | 10 ++++------ 5 files changed, 42 insertions(+), 26 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index f617554d..a93aa5bc 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -388,9 +388,6 @@ public struct TExtraFiles public string ComportName; public string DefaultComportName; - public int vendorID; - public int productID; - //public string IPaddress; //public int TCPport; @@ -3504,10 +3501,6 @@ private void ReadIniFile() //VP2SleepInterval = ini.GetValue("Station", "VP2SleepInterval", 0); DavisOptions.PeriodicDisconnectInterval = ini.GetValue("Station", "VP2PeriodicDisconnectInterval", 0); - - vendorID = ini.GetValue("Station", "VendorID", -1); - productID = ini.GetValue("Station", "ProductID", -1); - Latitude = ini.GetValue("Station", "Latitude", 0.0); if (Latitude > 90 || Latitude < -90) { @@ -3614,6 +3607,9 @@ private void ReadIniFile() FineOffsetOptions.FineOffsetSyncReads = ini.GetValue("Station", "SyncFOReads", true); FineOffsetOptions.FineOffsetReadAvoidPeriod = ini.GetValue("Station", "FOReadAvoidPeriod", 3); FineOffsetOptions.FineOffsetReadTime = ini.GetValue("Station", "FineOffsetReadTime", 150); + FineOffsetOptions.VendorID = ini.GetValue("Station", "VendorID", -1); + FineOffsetOptions.ProductID = ini.GetValue("Station", "ProductID", -1); + Units.Wind = ini.GetValue("Station", "Units.Wind", 0); Units.Press = ini.GetValue("Station", "PressureUnit", 0); @@ -4421,6 +4417,7 @@ internal void WriteIniFile() ini.SetValue("Station", "VP2TCPPort", DavisOptions.TCPPort); ini.SetValue("Station", "VP2IPAddr", DavisOptions.IPAddr); ini.SetValue("Station", "VP2PeriodicDisconnectInterval", DavisOptions.PeriodicDisconnectInterval); + ini.SetValue("Station", "ForceVPBarUpdate", DavisOptions.ForceVPBarUpdate); ini.SetValue("Station", "NoSensorCheck", StationOptions.NoSensorCheck); ini.SetValue("Station", "CalculatedDP", StationOptions.CalculatedDP); @@ -4434,12 +4431,16 @@ internal void WriteIniFile() ini.SetValue("Station", "SyncDavisClock", StationOptions.SyncTime); ini.SetValue("Station", "ClockSettingHour", StationOptions.ClockSettingHour); ini.SetValue("Station", "SyncFOReads", FineOffsetOptions.FineOffsetSyncReads); - ini.SetValue("Station", "FOReadAvoidPeriod", FineOffsetOptions.FineOffsetReadAvoidPeriod); - ini.SetValue("Station", "FineOffsetReadTime", FineOffsetOptions.FineOffsetReadTime); ini.SetValue("Station", "WS2300IgnoreStationClock", StationOptions.WS2300IgnoreStationClock); ini.SetValue("Station", "LogExtraSensors", StationOptions.LogExtraSensors); ini.SetValue("Station", "DataLogInterval", DataLogInterval); + ini.SetValue("Station", "FOReadAvoidPeriod", FineOffsetOptions.FineOffsetReadAvoidPeriod); + ini.SetValue("Station", "FineOffsetReadTime", FineOffsetOptions.FineOffsetReadTime); + ini.SetValue("Station", "VendorID", FineOffsetOptions.VendorID); + ini.SetValue("Station", "ProductID", FineOffsetOptions.ProductID); + + ini.SetValue("Station", "WindUnit", Units.Wind); ini.SetValue("Station", "PressureUnit", Units.Press); ini.SetValue("Station", "RainUnit", Units.Rain); @@ -4468,7 +4469,6 @@ internal void WriteIniFile() ini.SetValue("Station", "FCpressinMB", FCpressinMB); ini.SetValue("Station", "FClowpress", FClowpress); ini.SetValue("Station", "FChighpress", FChighpress); - ini.SetValue("Station", "ForceVPBarUpdate", DavisOptions.ForceVPBarUpdate); ini.SetValue("Station", "UseZeroBearing", StationOptions.UseZeroBearing); ini.SetValue("Station", "RoundWindSpeed", StationOptions.RoundWindSpeed); ini.SetValue("Station", "PrimaryAqSensor", StationOptions.PrimaryAqSensor); @@ -9272,7 +9272,9 @@ public class FineOffsetOptions public bool FineOffsetSyncReads { get; set; } public int FineOffsetReadAvoidPeriod { get; set; } public int FineOffsetReadTime { get; set; } - } + public int VendorID { get; set; } + public int ProductID { get; set; } +} public class ImetOptions { diff --git a/CumulusMX/FOStation.cs b/CumulusMX/FOStation.cs index 8ad42ad7..3bd98140 100644 --- a/CumulusMX/FOStation.cs +++ b/CumulusMX/FOStation.cs @@ -72,8 +72,8 @@ internal FOStation(Cumulus cumulus) : base(cumulus) var devicelist = DeviceList.Local; - int vid = (cumulus.vendorID < 0 ? DefaultVid : cumulus.vendorID); - int pid = (cumulus.productID < 0 ? DefaultPid : cumulus.productID); + int vid = (cumulus.FineOffsetOptions.VendorID < 0 ? DefaultVid : cumulus.FineOffsetOptions.VendorID); + int pid = (cumulus.FineOffsetOptions.ProductID < 0 ? DefaultPid : cumulus.FineOffsetOptions.ProductID); cumulus.LogMessage("Looking for Fine Offset station, VendorID=0x"+vid.ToString("X4")+" ProductID=0x"+pid.ToString("X4")); cumulus.LogConsoleMessage("Looking for Fine Offset station"); diff --git a/CumulusMX/Properties/AssemblyInfo.cs b/CumulusMX/Properties/AssemblyInfo.cs index f03aa2bc..f97d0353 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("Build 3108")] +[assembly: AssemblyDescription("Build 3109")] [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.10.0.3108")] -[assembly: AssemblyFileVersion("3.10.0.3108")] +[assembly: AssemblyVersion("3.10.0.3109")] +[assembly: AssemblyFileVersion("3.10.0.3109")] diff --git a/CumulusMX/StationSettings.cs b/CumulusMX/StationSettings.cs index 9c3d8d2b..bfafedd1 100644 --- a/CumulusMX/StationSettings.cs +++ b/CumulusMX/StationSettings.cs @@ -123,11 +123,18 @@ internal string GetStationAlpacaFormData() logrollover.time = "9am"; } + var fineoffsetadvanced = new JsonStationSettingsFineOffsetAdvanced() + { + readtime = cumulus.FineOffsetOptions.FineOffsetReadTime, + vid = cumulus.FineOffsetOptions.VendorID, + pid = cumulus.FineOffsetOptions.ProductID + }; + var fineoffset = new JsonStationSettingsFineOffset() { syncreads = cumulus.FineOffsetOptions.FineOffsetSyncReads, - readtime = cumulus.FineOffsetOptions.FineOffsetReadTime, - readavoid = cumulus.FineOffsetOptions.FineOffsetReadAvoidPeriod + readavoid = cumulus.FineOffsetOptions.FineOffsetReadAvoidPeriod, + advanced = fineoffsetadvanced }; var easyweather = new JsonStationSettingsEasyWeather() @@ -785,8 +792,10 @@ internal string UpdateStationConfig(IHttpContext context) if (settings.fineoffset != null) { cumulus.FineOffsetOptions.FineOffsetSyncReads = settings.fineoffset.syncreads; - cumulus.FineOffsetOptions.FineOffsetReadTime = settings.fineoffset.readtime; cumulus.FineOffsetOptions.FineOffsetReadAvoidPeriod = settings.fineoffset.readavoid; + cumulus.FineOffsetOptions.FineOffsetReadTime = settings.fineoffset.advanced.readtime; + cumulus.FineOffsetOptions.VendorID = settings.fineoffset.advanced.vid; + cumulus.FineOffsetOptions.ProductID = settings.fineoffset.advanced.pid; } } catch (Exception ex) @@ -1111,11 +1120,18 @@ internal class JsonStationSettingsDavisVp2Advanced public int baudrate { get; set; } } + internal class JsonStationSettingsFineOffsetAdvanced + { + public int readtime { get; set; } + public int vid { get; set; } + public int pid { get; set; } + } + internal class JsonStationSettingsFineOffset { public bool syncreads { get; set; } public int readavoid { get; set; } - public int readtime { get; set; } + public JsonStationSettingsFineOffsetAdvanced advanced { get; set; } } internal class JsonStationSettingsEasyWeather diff --git a/Updates.txt b/Updates.txt index e3b7773e..c14c4ba1 100644 --- a/Updates.txt +++ b/Updates.txt @@ -1,10 +1,8 @@ -3.10.0 - b3108 +3.10.0 - b3109 —————————————— -- Change: The following configuration items are now available via the settings screens - Davis - UseDavisLoop2 - DavisInitWaitTime - DavisIPResponseTime +- Change: All the settings screens revamped and reorganised. + - Many of the settings are now context senstive, only showing items relevant to your station and configuration + - Most of the previously config file "read-only" settings are now available in an Advanced section relevant to the configuration item. These settings are now read/write. From 7e27701e27b281860816a16dda2a71735f4c4c32 Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Fri, 12 Feb 2021 15:22:56 +0000 Subject: [PATCH 04/12] b3109 - Revised interfaces --- CumulusMX/Api.cs | 55 ++ CumulusMX/ApiTagProcessor.cs | 9 +- CumulusMX/CalibrationSettings.cs | 96 +-- CumulusMX/Cumulus.cs | 1102 +++++++++++++++--------------- CumulusMX/DataEditor.cs | 21 +- CumulusMX/DavisAirLink.cs | 2 +- CumulusMX/DavisStation.cs | 2 +- CumulusMX/DavisWllStation.cs | 9 +- CumulusMX/ExtraSensorSettings.cs | 36 +- CumulusMX/IniFile.cs | 26 +- CumulusMX/InternetSettings.cs | 230 ++++++- CumulusMX/NOAA.cs | 117 ++-- CumulusMX/NOAASettings.cs | 143 ++-- CumulusMX/Program.cs | 7 +- CumulusMX/StationSettings.cs | 68 +- CumulusMX/WMR100Station.cs | 2 +- CumulusMX/WMR200Station.cs | 6 +- CumulusMX/WeatherStation.cs | 554 ++++++--------- CumulusMX/webtags.cs | 2 +- Updates.txt | 24 +- 20 files changed, 1396 insertions(+), 1115 deletions(-) diff --git a/CumulusMX/Api.cs b/CumulusMX/Api.cs index b82fcc26..75cd5d23 100644 --- a/CumulusMX/Api.cs +++ b/CumulusMX/Api.cs @@ -65,6 +65,11 @@ public EditController(IHttpContext context) : base(context) [WebApiHandler(HttpVerbs.Get, RelativePath + "edit/*")] public async Task GetEditData() { + if (Station == null) + { + return await this.JsonResponseAsync("{}"); + } + try { // read the last segment of the URL to determine what data the caller wants @@ -129,6 +134,11 @@ public async Task GetEditData() [WebApiHandler(HttpVerbs.Post, RelativePath + "edit/*")] public async Task PostEditData() { + if (Station == null) + { + return await this.JsonResponseAsync("{}"); + } + try { // read the last segment of the URL to determine what data the caller wants @@ -203,6 +213,11 @@ public DataController(IHttpContext context) : base(context) [WebApiHandler(HttpVerbs.Get, RelativePath + "data/*")] public async Task GetData() { + if (Station == null) + { + return await this.JsonResponseAsync("{}"); + } + try { // read the last segment of the URL to determine what data the caller wants @@ -329,6 +344,11 @@ public GraphDataController(IHttpContext context) : base(context) [WebApiHandler(HttpVerbs.Get, RelativePath + "graphdata/*")] public async Task GetGraphData() { + if (Station == null) + { + return await this.JsonResponseAsync("{}"); + } + try { // read the last segment of the URL to determine what data the caller wants @@ -403,6 +423,11 @@ public async Task SetGraphData() [WebApiHandler(HttpVerbs.Get, RelativePath + "dailygraphdata/*")] public async Task GetDailyGraphData() { + if (Station == null) + { + return await this.JsonResponseAsync("{}"); + } + try { // read the last segment of the URL to determine what data the caller wants @@ -463,6 +488,11 @@ public RecordsController(IHttpContext context) : base(context) [WebApiHandler(HttpVerbs.Get, RelativePath + "records/alltime/*")] public async Task GetAlltimeData() { + if (Station == null) + { + return await this.JsonResponseAsync("{}"); + } + try { // read the last segment of the URL to determine what data the caller wants @@ -493,6 +523,11 @@ public async Task GetAlltimeData() [WebApiHandler(HttpVerbs.Get, RelativePath + "records/month/*")] public async Task GetMonthlyRecordData() { + if (Station == null) + { + return await this.JsonResponseAsync("{}"); + } + try { // read the last segment of the URL to determine what data the caller wants @@ -525,6 +560,11 @@ public async Task GetMonthlyRecordData() [WebApiHandler(HttpVerbs.Get, RelativePath + "records/thismonth/*")] public async Task GetThisMonthRecordData() { + if (Station == null) + { + return await this.JsonResponseAsync("{}"); + } + try { // read the last segment of the URL to determine what data the caller wants @@ -555,6 +595,11 @@ public async Task GetThisMonthRecordData() [WebApiHandler(HttpVerbs.Get, RelativePath + "records/thisyear/*")] public async Task GetThisYearRecordData() { + if (Station == null) + { + return await this.JsonResponseAsync("{}"); + } + try { // read the last segment of the URL to determine what data the caller wants @@ -604,6 +649,11 @@ public TodayYestDataController(IHttpContext context) : base(context) {} [WebApiHandler(HttpVerbs.Get, RelativePath + "todayyest/*")] public async Task GetYesterdayData() { + if (Station == null) + { + return await this.JsonResponseAsync("{}"); + } + try { // read the last segment of the URL to determine what data the caller wants @@ -655,6 +705,11 @@ public ExtraDataController(IHttpContext context) : base(context) { } [WebApiHandler(HttpVerbs.Get, RelativePath + "extra/*")] public async Task GetExtraData() { + if (Station == null) + { + return await this.JsonResponseAsync("{}"); + } + try { // read the last segment of the URL to determine what data the caller wants diff --git a/CumulusMX/ApiTagProcessor.cs b/CumulusMX/ApiTagProcessor.cs index b4f32d45..e4060a81 100644 --- a/CumulusMX/ApiTagProcessor.cs +++ b/CumulusMX/ApiTagProcessor.cs @@ -9,17 +9,20 @@ public class ApiTagProcessor { private readonly Cumulus cumulus; private readonly TokenParser tokenParser; - private readonly WebTags webtags; + private WebTags webtags; - internal ApiTagProcessor(Cumulus cumulus, WebTags webtags) + internal ApiTagProcessor(Cumulus cumulus) { this.cumulus = cumulus; - this.webtags = webtags; tokenParser = new TokenParser(); tokenParser.OnToken += cumulus.TokenParserOnToken; tokenParser.Encoding = new UTF8Encoding(false); } + internal void SetWebTags(WebTags webtags) + { + this.webtags = webtags; + } // Output the processed response as a JSON string public string ProcessJson(string query) diff --git a/CumulusMX/CalibrationSettings.cs b/CumulusMX/CalibrationSettings.cs index b545bce1..887b832f 100644 --- a/CumulusMX/CalibrationSettings.cs +++ b/CumulusMX/CalibrationSettings.cs @@ -50,7 +50,9 @@ public string UpdateCalibrationConfig(IHttpContext context) cumulus.Calib.WindSpeed.Mult = Convert.ToDouble(settings.multipliers.windspeed, invC); cumulus.Calib.WindGust.Mult = Convert.ToDouble(settings.multipliers.windgust, invC); cumulus.Calib.Temp.Mult = Convert.ToDouble(settings.multipliers.outdoortemp, invC); + cumulus.Calib.Temp.Mult2 = Convert.ToDouble(settings.multipliers.outdoortemp2, invC); cumulus.Calib.Hum.Mult = Convert.ToDouble(settings.multipliers.humidity, invC); + cumulus.Calib.Hum.Mult2 = Convert.ToDouble(settings.multipliers.humidity2, invC); cumulus.Calib.Rain.Mult = Convert.ToDouble(settings.multipliers.rainfall, invC); cumulus.Calib.Solar.Mult = Convert.ToDouble(settings.multipliers.solar, invC); cumulus.Calib.UV.Mult = Convert.ToDouble(settings.multipliers.uv, invC); @@ -100,58 +102,60 @@ public string GetCalibrationAlpacaFormData() { //var InvC = new CultureInfo(""); var offsets = new JsonCalibrationSettingsOffsets() - { - pressure = cumulus.Calib.Press.Offset, - temperature = cumulus.Calib.Temp.Offset, - indoortemp = cumulus.Calib.InTemp.Offset, - humidity = (int)cumulus.Calib.Hum.Offset, - winddir = (int)cumulus.Calib.WindDir.Offset, - solar = cumulus.Calib.Solar.Offset, - uv = cumulus.Calib.UV.Offset, - wetbulb = cumulus.Calib.WetBulb.Offset - }; + { + pressure = cumulus.Calib.Press.Offset, + temperature = cumulus.Calib.Temp.Offset, + indoortemp = cumulus.Calib.InTemp.Offset, + humidity = (int)cumulus.Calib.Hum.Offset, + winddir = (int)cumulus.Calib.WindDir.Offset, + solar = cumulus.Calib.Solar.Offset, + uv = cumulus.Calib.UV.Offset, + wetbulb = cumulus.Calib.WetBulb.Offset + }; + var multipliers = new JsonCalibrationSettingsMultipliers() - { - pressure = cumulus.Calib.Press.Mult, - windspeed = cumulus.Calib.WindSpeed.Mult, - windgust = cumulus.Calib.WindGust.Mult, - humidity = cumulus.Calib.Hum.Mult, - outdoortemp = cumulus.Calib.Temp.Mult, - rainfall = cumulus.Calib.Rain.Mult, - solar = cumulus.Calib.Solar.Mult, - uv = cumulus.Calib.UV.Mult, - wetbulb = cumulus.Calib.WetBulb.Mult - }; + { + pressure = cumulus.Calib.Press.Mult, + windspeed = cumulus.Calib.WindSpeed.Mult, + windgust = cumulus.Calib.WindGust.Mult, + humidity = cumulus.Calib.Hum.Mult, + humidity2 = cumulus.Calib.Hum.Mult2, + outdoortemp = cumulus.Calib.Temp.Mult, + outdoortemp2 = cumulus.Calib.Temp.Mult2, + rainfall = cumulus.Calib.Rain.Mult, + solar = cumulus.Calib.Solar.Mult, + uv = cumulus.Calib.UV.Mult, + wetbulb = cumulus.Calib.WetBulb.Mult + }; var spikeremoval = new JsonCalibrationSettingsSpikeRemoval() - { - humidity = cumulus.Spike.HumidityDiff, - windgust = cumulus.Spike.GustDiff, - windspeed = cumulus.Spike.WindDiff, - outdoortemp = cumulus.Spike.TempDiff, - maxhourlyrain = cumulus.Spike.MaxHourlyRain, - maxrainrate = cumulus.Spike.MaxRainRate, - pressure = cumulus.Spike.PressDiff - }; + { + humidity = cumulus.Spike.HumidityDiff, + windgust = cumulus.Spike.GustDiff, + windspeed = cumulus.Spike.WindDiff, + outdoortemp = cumulus.Spike.TempDiff, + maxhourlyrain = cumulus.Spike.MaxHourlyRain, + maxrainrate = cumulus.Spike.MaxRainRate, + pressure = cumulus.Spike.PressDiff + }; var limits = new JsonCalibrationSettingsLimits() - { - temphigh = cumulus.Limit.TempHigh, - templow = cumulus.Limit.TempLow, - dewhigh = cumulus.Limit.DewHigh, - presshigh = cumulus.Limit.PressHigh, - presslow = cumulus.Limit.PressLow, - windhigh = cumulus.Limit.WindHigh - }; - + { + temphigh = cumulus.Limit.TempHigh, + templow = cumulus.Limit.TempLow, + dewhigh = cumulus.Limit.DewHigh, + presshigh = cumulus.Limit.PressHigh, + presslow = cumulus.Limit.PressLow, + windhigh = cumulus.Limit.WindHigh + }; var data = new JsonCalibrationSettingsData() - { - offsets = offsets, - multipliers = multipliers, - spikeremoval = spikeremoval, - limits = limits, - log = cumulus.ErrorLogSpikeRemoval + { + offsets = offsets, + multipliers = multipliers, + spikeremoval = spikeremoval, + limits = limits, + log = cumulus.ErrorLogSpikeRemoval }; return data.ToJson(); @@ -203,7 +207,9 @@ public class JsonCalibrationSettingsMultipliers public double windspeed { get; set; } public double windgust { get; set; } public double outdoortemp { get; set; } + public double outdoortemp2 { get; set; } public double humidity { get; set; } + public double humidity2 { get; set; } public double rainfall { get; set; } public double solar { get; set; } public double uv { get; set; } diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index a93aa5bc..aac5ef95 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -447,21 +447,6 @@ public struct TExtraFiles private readonly string backupPath; //private readonly string ExternaldataFile; public string WebTagFile; - private readonly string webIndexFile; - private readonly string webTodayFile; - private readonly string webYesterFile; - private readonly string webRecordFile; - private readonly string webTrendsFile; - private readonly string webHistoricFile; - private readonly string webSelectaChartFile; - private readonly string webGaugesFile; - private readonly string webThisMonthFile; - private readonly string webThisYearFile; - private readonly string MonthlyRecordFile; - - private readonly string[] localWebTemplateFiles; - private readonly string[] localWebTextFiles; - private readonly string[] remoteWebTextFiles; public bool SynchronisedWebUpdate; @@ -508,8 +493,6 @@ public struct TExtraFiles public bool RealtimeEnabled; // The timer is to be started public bool RealtimeFTPEnabled; // The FTP connection is to be established - public bool RealtimeTxtFTP; // The realtime.txt file is to be uploaded - public bool RealtimeGaugesTxtFTP; // The realtimegauges.txt file is to be uploaded private int realtimeFTPRetries; // Count of failed realtime FTP attempts // Twitter settings @@ -591,7 +574,6 @@ public struct MqttSettings public double[] NOAARainNorms = new double[13]; public bool EODfilesNeedFTP; - public bool DailyGraphDataFilesNeedFTP; public bool IsOSX; public double CPUtemp = -999; @@ -746,107 +728,6 @@ public struct MqttSettings public string loggingfile; - /* - CryptoLicense lic = new CryptoLicense(); - - //create code for applicationsecret - byte[] applicationSecret = Convert.FromBase64String("QpJGpsqWfkKu+yM8Ljp6+A=="); - //create code for public key - byte[] publicKey = Convert.FromBase64String("BgIAAACkAABSU0ExAAIAAAEAAQBlt7KZEJ8lk7Pa+MSYzToupycyYtGKNmSBYEb2UTiGpDxsxH8vzGDyWv5ytW1qlaPwaVeJLtagn7/mep/Yr16m"); - private Habanero.Licensing.Validation.LicenseValidator Validator - { - get - { - //this version is for file system - Isolated storage is anther option - return new Habanero.Licensing.Validation.LicenseValidator(Habanero.Licensing.Validation.LicenseLocation.File, "licence.lic", "Cumulus MX", publicKey, applicationSecret, ThisVersion); - } - } - - private static Version ThisVersion - { - get - { - //Get the executing files filesversion - var fileversion = System.Diagnostics.FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location); - var thisVersion = new Version(fileversion.FileMajorPart, fileversion.FileMinorPart, fileversion.FileBuildPart, fileversion.FilePrivatePart); - - return thisVersion; - } - } - - private void DoLicenseCheck() - { - LicenseValidationResult result = Validator.CheckLicense(); - if ((result.License.Product.LicenseName != null) && (result.License.Product.ProductName != null) && (result.License.LicensedTo != null) && (result.License.Product.MaxVersion != null)) - { - Console.WriteLine(result.License.Product.LicenseName+" licence for "+result.License.Product.ProductName+" " + result.License.Product.MaxVersion + - " for user "+result.License.LicensedTo); - } - - if (result.ExpirationDate != null) - { - Console.WriteLine("Licence expiry date: "+result.ExpirationDate.Value.ToString("D")); - } - - if (result.State == LicenseState.Invalid) - { - if (result.Issues.Contains(LicenseIssue.NoLicenseInfo)) - { - //inform user there is no license info - Console.WriteLine("No licence information, please obtain a licence"); - Environment.Exit(0); - } - else - { - if (result.Issues.Contains(LicenseIssue.ExpiredDateSoft)) - { - //inform user that their license has expired but - //that they may continue using the software for a period - Console.WriteLine("Licence expired, please obtain a licence"); - Environment.Exit(0); - } - if (result.Issues.Contains(LicenseIssue.ExpiredDateHard)) - { - //inform user that their license has expired - Console.WriteLine("Licence expired, please obtain a licence"); - Environment.Exit(0); - } - if (result.Issues.Contains(LicenseIssue.ExpiredVersion)) - { - //inform user that their license is for an earlier version - Console.WriteLine("Licence is for an earlier version, please obtain a new licence"); - Environment.Exit(0); - } - //other messages - } - - //prompt user for trial or to insert license info then decide what to do - //activate trial - result = Validator.ActivateTrial(45); - //or save license - string userLicense = "Get the license string from your user"; - result = Validator.CheckLicense(userLicense); - //decide if you want to save the license... - Validator.SaveLicense(userLicense); - } - if (result.State == LicenseState.Trial) - { - //activate trial features - Console.WriteLine("Trial licence is valid"); - } - if (result.State == LicenseState.Valid) - { - //activate product - if (Validator.IsEdition("Pro")) - { - //activate pro features... - } - - Console.WriteLine("Licence is valid"); - } - } - */ - public Cumulus(int HTTPport, bool DebugEnabled, string startParms) { var fullVer = Assembly.GetExecutingAssembly().GetName().Version; @@ -963,36 +844,6 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) YearIniFile = Datapath + "year.ini"; //stringsFile = "strings.ini"; - IndexTFile = WebPath + "indexT.htm"; - TodayTFile = WebPath + "todayT.htm"; - YesterdayTFile = WebPath + "yesterdayT.htm"; - RecordTFile = WebPath + "recordT.htm"; - TrendsTFile = WebPath + "trendsT.htm"; - GaugesTFile = WebPath + "gaugesT.htm"; - ThisMonthTFile = WebPath + "thismonthT.htm"; - ThisYearTFile = WebPath + "thisyearT.htm"; - MonthlyRecordTFile = WebPath + "monthlyrecordT.htm"; - HistoricTFile = WebPath + "historicT.htm"; - SelectaChartTFile = WebPath + "selectachartT.htm"; - RealtimeGaugesTxtTFile = WebPath + "realtimegaugesT.txt"; - - webIndexFile = WebPath + "index.htm"; - webTodayFile = WebPath + "today.htm"; - webYesterFile = WebPath + "yesterday.htm"; - webRecordFile = WebPath + "record.htm"; - webTrendsFile = WebPath + "trends.htm"; - webGaugesFile = WebPath + "gauges.htm"; - webThisMonthFile = WebPath + "thismonth.htm"; - webThisYearFile = WebPath + "thisyear.htm"; - MonthlyRecordFile = WebPath + "monthlyrecord.htm"; - webHistoricFile = WebPath + "historic.htm"; - webSelectaChartFile = WebPath + "selectachart.htm"; - RealtimeGaugesTxtFile = WebPath + "realtimegauges.txt"; - - localWebTemplateFiles = new[] { IndexTFile, TodayTFile, YesterdayTFile, RecordTFile, TrendsTFile, GaugesTFile, ThisMonthTFile, ThisYearTFile, MonthlyRecordTFile, HistoricTFile, SelectaChartTFile }; - localWebTextFiles = new[] { webIndexFile, webTodayFile, webYesterFile, webRecordFile, webTrendsFile, webGaugesFile, webThisMonthFile, webThisYearFile, MonthlyRecordFile, webHistoricFile, webSelectaChartFile }; - remoteWebTextFiles = new[] { "index.htm", "today.htm", "yesterday.htm", "record.htm", "trends.htm", "gauges.htm", "thismonth.htm", "thisyear.htm", "monthlyrecord.htm", "historic.htm", "selectachart.htm" }; - // Set the default upload intervals for web services Wund.DefaultInterval = 15; Windy.DefaultInterval = 15; @@ -1002,6 +853,153 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) WCloud.DefaultInterval = 10; OpenWeatherMap.DefaultInterval = 15; + StdWebFiles = new FileGenerationFtpOptions[2]; + StdWebFiles[0] = new FileGenerationFtpOptions() + { + TemplateFileName = WebPath + "websitedataT.json", + LocalPath = WebPath, + LocalFileName = "websitedata.json", + RemoteFileName = "websitedata.json" + }; + StdWebFiles[1] = new FileGenerationFtpOptions() + { + LocalPath = "", + LocalFileName = "wxnow.txt", + RemoteFileName = "wxnow.txt" + }; + + RealtimeFiles = new FileGenerationFtpOptions[2]; + RealtimeFiles[0] = new FileGenerationFtpOptions() + { + LocalFileName = "realtime.txt", + RemoteFileName = "realtime.txt" + }; + RealtimeFiles[1] = new FileGenerationFtpOptions() + { + TemplateFileName = WebPath + "realtimegaugesT.txt", + LocalPath = WebPath, + LocalFileName = "realtimegauges.txt", + RemoteFileName = "realtimegauges.txt" + }; + + GraphDataFiles = new FileGenerationFtpOptions[13]; + GraphDataFiles[0] = new FileGenerationFtpOptions() + { + LocalPath = WebPath, + LocalFileName = "graphconfig.json", + RemoteFileName = "graphconfig.json" + }; + GraphDataFiles[1] = new FileGenerationFtpOptions() + { + LocalPath = WebPath, + LocalFileName = "availabledata.json", + RemoteFileName = "availabledata.json" + }; + GraphDataFiles[2] = new FileGenerationFtpOptions() + { + LocalPath = WebPath, + LocalFileName = "tempdata.json", + RemoteFileName ="tempdata.json" + }; + GraphDataFiles[3] = new FileGenerationFtpOptions() + { + LocalPath = WebPath, + LocalFileName = "pressdata.json", + RemoteFileName = "pressdata.json" + }; + GraphDataFiles[4] = new FileGenerationFtpOptions() + { + LocalPath = WebPath, + LocalFileName = "winddata.json", + RemoteFileName = "winddata.json" + }; + GraphDataFiles[5] = new FileGenerationFtpOptions() + { + LocalPath = WebPath, + LocalFileName = "wdirdata.json", + RemoteFileName = "wdirdata.json" + }; + GraphDataFiles[6] = new FileGenerationFtpOptions() + { + LocalPath = WebPath, + LocalFileName = "humdata.json", + RemoteFileName = "humdata.json" + }; + GraphDataFiles[7] = new FileGenerationFtpOptions() + { + LocalPath = WebPath, + LocalFileName = "raindata.json", + RemoteFileName = "raindata.json" + }; + GraphDataFiles[8] = new FileGenerationFtpOptions() + { + LocalPath = WebPath, + LocalFileName = "dailyrain.json", + RemoteFileName = "dailyrain.json" + }; + GraphDataFiles[9] = new FileGenerationFtpOptions() + { + LocalPath = WebPath, + LocalFileName = "dailytemp.json", + RemoteFileName = "dailytemp.json" + }; + GraphDataFiles[10] = new FileGenerationFtpOptions() + { + LocalPath = WebPath, + LocalFileName = "solardata.json", + RemoteFileName = "solardata.json" + }; + GraphDataFiles[11] = new FileGenerationFtpOptions() + { + LocalPath = WebPath, + LocalFileName = "sunhours.json", + RemoteFileName = "sunhours.json" + }; + GraphDataFiles[12] = new FileGenerationFtpOptions() + { + LocalPath = WebPath, + LocalFileName = "airquality.json", + RemoteFileName = "airquality.json" + }; + + GraphDataEodFiles = new FileGenerationFtpOptions[6]; + GraphDataEodFiles[0] = new FileGenerationFtpOptions() + { + LocalPath = WebPath, + LocalFileName = "alldailytempdata.json", + RemoteFileName = "alldailytempdata.json" + }; + GraphDataEodFiles[1] = new FileGenerationFtpOptions() + { + LocalPath = WebPath, + LocalFileName = "alldailypressdata.json", + RemoteFileName = "alldailypressdata.json" + }; + GraphDataEodFiles[2] = new FileGenerationFtpOptions() + { + LocalPath = WebPath, + LocalFileName = "alldailywinddata.json", + RemoteFileName = "alldailywinddata.json" + }; + GraphDataEodFiles[3] = new FileGenerationFtpOptions() + { + LocalPath = WebPath, + LocalFileName = "alldailyhumdata.json", + RemoteFileName = "alldailyhumdata.json" + }; + GraphDataEodFiles[4] = new FileGenerationFtpOptions() + { + LocalPath = WebPath, + LocalFileName = "alldailyraindata.json", + RemoteFileName = "alldailyraindata.json" + }; + GraphDataEodFiles[5] = new FileGenerationFtpOptions() + { + LocalPath = WebPath, + LocalFileName = "alldailysolardata.json", + RemoteFileName = "alldailysolardata.json" + }; + ReadIniFile(); // Do we prevent more than one copy of CumulusMX running? @@ -1106,80 +1104,6 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) GC.Collect(); - remoteGraphdataFiles = new[] - { - "graphconfig.json", // 0 - "tempdata.json", // 1 - "pressdata.json", // 2 - "winddata.json", // 3 - "wdirdata.json", // 4 - "humdata.json", // 5 - "raindata.json", // 6 - "dailyrain.json", // 7 - "dailytemp.json", // 8 - "solardata.json", // 9 - "sunhours.json", // 10 - "airquality.json", // 11 - "availabledata.json" // 12 - }; - - localGraphdataFiles = new[] - { - "web" + DirectorySeparator + remoteGraphdataFiles[0], // 0 - "web" + DirectorySeparator + remoteGraphdataFiles[1], // 1 - "web" + DirectorySeparator + remoteGraphdataFiles[2], // 2 - "web" + DirectorySeparator + remoteGraphdataFiles[3], // 3 - "web" + DirectorySeparator + remoteGraphdataFiles[4], // 4 - "web" + DirectorySeparator + remoteGraphdataFiles[5], // 5 - "web" + DirectorySeparator + remoteGraphdataFiles[6], // 6 - "web" + DirectorySeparator + remoteGraphdataFiles[7], // 7 - "web" + DirectorySeparator + remoteGraphdataFiles[8], // 8 - "web" + DirectorySeparator + remoteGraphdataFiles[9], // 9 - "web" + DirectorySeparator + remoteGraphdataFiles[10], // 10 - "web" + DirectorySeparator + remoteGraphdataFiles[11], // 11 - "web" + DirectorySeparator + remoteGraphdataFiles[12] // 12 - }; - - remoteDailyGraphdataFiles = new[] - { - "alldailytempdata.json", - "alldailypressdata.json", - "alldailywinddata.json", - "alldailyhumdata.json", - "alldailyraindata.json", - "alldailysolardata.json" - }; - - localDailyGraphdataFiles = new[] - { - "web" + DirectorySeparator + remoteDailyGraphdataFiles[0], // 0 - "web" + DirectorySeparator + remoteDailyGraphdataFiles[1], // 1 - "web" + DirectorySeparator + remoteDailyGraphdataFiles[2], // 2 - "web" + DirectorySeparator + remoteDailyGraphdataFiles[3], // 3 - "web" + DirectorySeparator + remoteDailyGraphdataFiles[4], // 4 - "web" + DirectorySeparator + remoteDailyGraphdataFiles[5] // 5 - }; - - - /* - if (GraphOptions.SolarVisible || GraphOptions.UVVisible) - { - Array.Resize(ref localGraphdataFiles, localGraphdataFiles.Length + 1); - localGraphdataFiles[localGraphdataFiles.Length - 1] = "web" + DirectorySeparator + "solardata.json"; - - Array.Resize(ref remoteGraphdataFiles, remoteGraphdataFiles.Length + 1); - remoteGraphdataFiles[remoteGraphdataFiles.Length - 1] = "solardata.json"; - } - if (GraphOptions.SolarVisible) - { - Array.Resize(ref localGraphdataFiles, localGraphdataFiles.Length + 1); - localGraphdataFiles[localGraphdataFiles.Length - 1] = "web" + DirectorySeparator + "sunhours.json"; - - Array.Resize(ref remoteGraphdataFiles, remoteGraphdataFiles.Length + 1); - remoteGraphdataFiles[remoteGraphdataFiles.Length - 1] = "sunhours.json"; - } - */ - LogMessage("Data path = " + Datapath); AppDomain.CurrentDomain.SetData("DataDirectory", Datapath); @@ -1329,6 +1253,42 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) LogMessage("Cumulus Starting"); + // switch off logging from Unosquare.Swan which underlies embedIO + Unosquare.Swan.Terminal.Settings.DisplayLoggingMessageType = Unosquare.Swan.LogMessageType.Fatal; + + httpServer = new WebServer(HTTPport, RoutingStrategy.Wildcard); + + var assemblyPath = Path.GetDirectoryName(typeof(Program).Assembly.Location); + var htmlRootPath = Path.Combine(assemblyPath, "interface"); + + LogMessage("HTML root path = " + htmlRootPath); + + httpServer.RegisterModule(new StaticFilesModule(htmlRootPath, new Dictionary() { { "Cache-Control", "max-age=300" } })); + httpServer.Module().UseRamCache = true; + + // Set up the API web server + // Soem APi functions require the station, so set them after station initialisation + Api.Setup(httpServer); + Api.programSettings = new ProgramSettings(this); + Api.stationSettings = new StationSettings(this); + Api.internetSettings = new InternetSettings(this); + Api.extraSensorSettings = new ExtraSensorSettings(this); + Api.calibrationSettings = new CalibrationSettings(this); + Api.noaaSettings = new NOAASettings(this); + Api.alarmSettings = new AlarmSettings(this); + Api.mySqlSettings = new MysqlSettings(this); + Api.dataEditor = new DataEditor(this); + Api.tagProcessor = new ApiTagProcessor(this); + + // Set up the Web Socket server + WebSocket.Setup(httpServer, this); + + httpServer.RunAsync(); + + LogConsoleMessage("Cumulus running at: " + httpServer.Listener.Prefixes.First()); + LogConsoleMessage(" (Replace * with any IP address on this machine, or localhost)"); + LogConsoleMessage(" Open the admin interface by entering this URL in a browser."); + LogDebugMessage("Lock: Cumulus waiting for the lock"); syncInit.Wait(); LogDebugMessage("Lock: Cumulus has lock"); @@ -1392,6 +1352,10 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) if (station != null) { + Api.Station = station; + Api.stationSettings.SetStation(station); + Api.dataEditor.SetStation(station); + LogMessage("Creating extra sensors"); if (AirLinkInEnabled) { @@ -1403,118 +1367,78 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) airLinkDataOut = new AirLinkData(); airLinkOut = new DavisAirLink(this, false, station); } - } - - webtags = new WebTags(this, station); - webtags.InitialiseWebtags(); - tokenParser = new TokenParser(); - tokenParser.OnToken += TokenParserOnToken; + webtags = new WebTags(this, station); + webtags.InitialiseWebtags(); - realtimeTokenParser = new TokenParser(); - realtimeTokenParser.OnToken += TokenParserOnToken; + Api.dataEditor.SetWebTags(webtags); + Api.tagProcessor.SetWebTags(webtags); + tokenParser = new TokenParser(); + tokenParser.OnToken += TokenParserOnToken; - // switch off logging from Unosquare.Swan which underlies embedIO - Unosquare.Swan.Terminal.Settings.DisplayLoggingMessageType = Unosquare.Swan.LogMessageType.Fatal; + realtimeTokenParser = new TokenParser(); + realtimeTokenParser.OnToken += TokenParserOnToken; - httpServer = new WebServer(HTTPport, RoutingStrategy.Wildcard); + RealtimeTimer.Interval = RealtimeInterval; + RealtimeTimer.Elapsed += RealtimeTimerTick; + RealtimeTimer.AutoReset = true; - var assemblyPath = Path.GetDirectoryName(typeof(Program).Assembly.Location); - var htmlRootPath = Path.Combine(assemblyPath, "interface"); + SetFtpLogging(FTPlogging); - LogMessage("HTML root path = " + htmlRootPath); + TwitterTimer.Elapsed += TwitterTimerTick; - httpServer.RegisterModule(new StaticFilesModule(htmlRootPath, new Dictionary(){{"Cache-Control", "max-age=300"}})); - httpServer.Module().UseRamCache = true; + WundTimer.Elapsed += WundTimerTick; + WindyTimer.Elapsed += WindyTimerTick; + PWSTimer.Elapsed += PWSTimerTick; + WOWTimer.Elapsed += WowTimerTick; + AwekasTimer.Elapsed += AwekasTimerTick; + WCloudTimer.Elapsed += WCloudTimerTick; + APRStimer.Elapsed += APRSTimerTick; + OpenWeatherMapTimer.Elapsed += OpenWeatherMapTimerTick; + WebTimer.Elapsed += WebTimerTick; + xapsource = "sanday.cumulus." + Environment.MachineName; - // Set up the API web server - Api.Setup(httpServer); - Api.Station = station; - Api.programSettings = new ProgramSettings(this); - Api.stationSettings = new StationSettings(this, station); - Api.internetSettings = new InternetSettings(this); - Api.extraSensorSettings = new ExtraSensorSettings(this); - Api.calibrationSettings = new CalibrationSettings(this); - Api.noaaSettings = new NOAASettings(this); - Api.alarmSettings = new AlarmSettings(this); - Api.mySqlSettings = new MysqlSettings(this); - Api.dataEditor = new DataEditor(this, station, webtags); - Api.tagProcessor = new ApiTagProcessor(this, webtags); + xapHeartbeat = "xap-hbeat\n{\nv=12\nhop=1\nuid=FF" + xapUID + "00\nclass=xap-hbeat.alive\nsource=" + xapsource + "\ninterval=60\n}"; - // Set up the Web Socket server - WebSocket.Setup(httpServer, this); - - httpServer.RunAsync(); - - LogConsoleMessage("Cumulus running at: " + httpServer.Listener.Prefixes.First()); - LogConsoleMessage(" (Replace * with any IP address on this machine, or localhost)"); - LogConsoleMessage(" Open the admin interface by entering this URL in a browser."); - - - RealtimeTimer.Interval = RealtimeInterval; - RealtimeTimer.Elapsed += RealtimeTimerTick; - RealtimeTimer.AutoReset = true; - - SetFtpLogging(FTPlogging); - - TwitterTimer.Elapsed += TwitterTimerTick; - - WundTimer.Elapsed += WundTimerTick; - WindyTimer.Elapsed += WindyTimerTick; - PWSTimer.Elapsed += PWSTimerTick; - WOWTimer.Elapsed += WowTimerTick; - AwekasTimer.Elapsed += AwekasTimerTick; - WCloudTimer.Elapsed += WCloudTimerTick; - APRStimer.Elapsed += APRSTimerTick; - OpenWeatherMapTimer.Elapsed += OpenWeatherMapTimerTick; - WebTimer.Elapsed += WebTimerTick; - - xapsource = "sanday.cumulus." + Environment.MachineName; + if (xapEnabled) + { + Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + IPEndPoint iep1 = new IPEndPoint(IPAddress.Broadcast, xapPort); - xapHeartbeat = "xap-hbeat\n{\nv=12\nhop=1\nuid=FF" + xapUID + "00\nclass=xap-hbeat.alive\nsource=" + xapsource + "\ninterval=60\n}"; + byte[] data = Encoding.ASCII.GetBytes(xapHeartbeat); - if (xapEnabled) - { - Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - IPEndPoint iep1 = new IPEndPoint(IPAddress.Broadcast, xapPort); + sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); + sock.SendTo(data, iep1); + sock.Close(); + } - byte[] data = Encoding.ASCII.GetBytes(xapHeartbeat); + if (MQTT.EnableDataUpdate || MQTT.EnableInterval) + { + MqttPublisher.Setup(this); - sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); - sock.SendTo(data, iep1); - sock.Close(); - } + if (MQTT.EnableInterval) + { + MQTTTimer.Elapsed += MQTTTimerTick; + } + } - if (MQTT.EnableDataUpdate || MQTT.EnableInterval) - { - MqttPublisher.Setup(this); + InitialiseRG11(); - if (MQTT.EnableInterval) + if (station.timerStartNeeded) { - MQTTTimer.Elapsed += MQTTTimerTick; + StartTimersAndSensors(); } - } - - InitialiseRG11(); - if (station != null && station.timerStartNeeded) - { - StartTimersAndSensors(); - } - - if (station != null && (StationType == StationTypes.WMR100) || (StationType == StationTypes.EasyWeather) || (Manufacturer == OREGON)) - { - station.StartLoop(); - } + if ((StationType == StationTypes.WMR100) || (StationType == StationTypes.EasyWeather) || (Manufacturer == OREGON)) + { + station.StartLoop(); + } - // If enabled generate the daily graph data files, and upload at first opportunity - if (station != null) - { + // If enabled generate the daily graph data files, and upload at first opportunity LogDebugMessage("Generating the daily graph data files"); station.CreateEodGraphDataFiles(); - DailyGraphDataFilesNeedFTP = IncludeGraphDataFiles; } LogDebugMessage("Lock: Cumulus releasing the lock"); @@ -1672,7 +1596,7 @@ internal void SetStartOfMonthlyInsertSQL() internal void SetupUnitText() { - switch (TempUnit) + switch (Units.Temp) { case 0: Units.TempText = "°C"; @@ -1684,7 +1608,7 @@ internal void SetupUnitText() break; } - switch (RainUnit) + switch (Units.Rain) { case 0: Units.RainText = "mm"; @@ -2450,7 +2374,7 @@ internal void RealtimeTimerTick(object sender, ElapsedEventArgs elapsedEventArgs CreateRealtimeHTMLfiles(cycle); RealtimeCopyInProgress = false; - if (RealtimeFTPEnabled) + if (RealtimeFTPEnabled && !string.IsNullOrWhiteSpace(FtpHostname)) { // Is a previous cycle still running? if (RealtimeFtpInProgress) @@ -2619,45 +2543,35 @@ private void RealtimeFTPConnectionTest(uint cycle) private void RealtimeFTPUpload(byte cycle) { - // realtime.txt - string filepath, gaugesfilepath; + var remotePath = ""; - if (FtpDirectory.Length == 0) - { - filepath = "realtime.txt"; - gaugesfilepath = "realtimegauges.txt"; - } - else + if (FtpDirectory.Length > 0) { - var remotePath = (FtpDirectory.EndsWith("/") ? FtpDirectory : FtpDirectory + "/"); - filepath = remotePath + "/realtime.txt"; - gaugesfilepath = remotePath + "/realtimegauges.txt"; + remotePath = (FtpDirectory.EndsWith("/") ? FtpDirectory : FtpDirectory + "/"); } - if (RealtimeTxtFTP) + for (var i = 0; i < RealtimeFiles.Length; i++) { - LogFtpMessage($"Realtime[{cycle}]: Uploading - realtime.txt"); - if (Sslftp == FtpProtocols.SFTP) - { - UploadFile(RealtimeSSH, RealtimeFile, filepath, cycle); - } - else + if (RealtimeFiles[i].Create && RealtimeFiles[i].FTP) { - UploadFile(RealtimeFTP, RealtimeFile, filepath, cycle); - } - } + var remoteFile = remotePath + RealtimeFiles[i].RemoteFileName; + var localFile = RealtimeFiles[i].LocalPath + RealtimeFiles[i].LocalFileName; + + if (RealtimeFiles[i].Create && !string.IsNullOrWhiteSpace(RealtimeFiles[i].TemplateFileName)) + { + ProcessTemplateFile(RealtimeFiles[i].TemplateFileName, localFile, tokenParser); + } + + LogFtpMessage($"Realtime[{cycle}]: Uploading - {RealtimeFiles[i].LocalFileName}"); + if (Sslftp == FtpProtocols.SFTP) + { + UploadFile(RealtimeSSH, localFile, remoteFile, cycle); + } + else + { + UploadFile(RealtimeFTP, localFile, remoteFile, cycle); + } - if (RealtimeGaugesTxtFTP) - { - ProcessTemplateFile(RealtimeGaugesTxtTFile, RealtimeGaugesTxtFile, realtimeTokenParser); - LogFtpMessage($"Realtime[{cycle}]: Uploading - realtimegauges.txt"); - if (Sslftp == FtpProtocols.SFTP) - { - UploadFile(RealtimeSSH, RealtimeGaugesTxtFile, gaugesfilepath, cycle); - } - else - { - UploadFile(RealtimeFTP, RealtimeGaugesTxtFile, gaugesfilepath, cycle); } } @@ -2715,6 +2629,17 @@ private void RealtimeFTPUpload(byte cycle) private void CreateRealtimeHTMLfiles(int cycle) { + // Process realtime files + for (var i = 0; i < RealtimeFiles.Length; i++) + { + if (RealtimeFiles[i].Create && !string.IsNullOrWhiteSpace(RealtimeFiles[i].TemplateFileName)) + { + LogDebugMessage($"Realtime[{cycle}]: Processing realtime file - {RealtimeFiles[i].LocalFileName}"); + var destFile = RealtimeFiles[i].LocalPath + RealtimeFiles[i].LocalFileName; + ProcessTemplateFile(RealtimeFiles[i].TemplateFileName, destFile, realtimeTokenParser); + } + } + for (int i = 0; i < numextrafiles; i++) { if (ExtraFiles[i].realtime) @@ -3611,7 +3536,7 @@ private void ReadIniFile() FineOffsetOptions.ProductID = ini.GetValue("Station", "ProductID", -1); - Units.Wind = ini.GetValue("Station", "Units.Wind", 0); + Units.Wind = ini.GetValue("Station", "WindUnit", 0); Units.Press = ini.GetValue("Station", "PressureUnit", 0); Units.Rain = ini.GetValue("Station", "RainUnit", 0); @@ -3622,8 +3547,8 @@ private void ReadIniFile() // Unit decimals - RainDPlaces = RainDPlaceDefaults[RainUnit]; - TempDPlaces = TempDPlaceDefaults[TempUnit]; + RainDPlaces = RainDPlaceDefaults[Units.Rain]; + TempDPlaces = TempDPlaceDefaults[Units.Temp]; PressDPlaces = PressDPlaceDefaults[Units.Press]; WindDPlaces = StationOptions.RoundWindSpeed ? 0 : WindDPlaceDefaults[Units.Wind]; WindAvgDPlaces = WindDPlaces; @@ -3729,7 +3654,7 @@ private void ReadIniFile() if (ChillHourThreshold < -998) { - ChillHourThreshold = TempUnit == 0 ? 7 : 45; + ChillHourThreshold = Units.Temp == 0 ? 7 : 45; } if (FCPressureThreshold < 0) @@ -3737,8 +3662,8 @@ private void ReadIniFile() FCPressureThreshold = Units.Press == 2 ? 0.00295333727 : 0.1; } - special_logging = ini.GetValue("Station", "SpecialLog", false); - solar_logging = ini.GetValue("Station", "SolarLog", false); + //special_logging = ini.GetValue("Station", "SpecialLog", false); + //solar_logging = ini.GetValue("Station", "SolarLog", false); //RTdisconnectcount = ini.GetValue("Station", "RTdisconnectcount", 0); @@ -3747,8 +3672,6 @@ private void ReadIniFile() WMR200TempChannel = ini.GetValue("Station", "WMR200TempChannel", 1); - CreateWxnowTxt = ini.GetValue("Station", "CreateWxnowTxt", false); - ListWebTags = ini.GetValue("Station", "ListWebTags", false); // WeatherLink Live device settings @@ -3797,21 +3720,29 @@ private void ReadIniFile() Gw1000AutoUpdateIpAddress = ini.GetValue("GW1000", "AutoUpdateIpAddress", true); // AirLink settings + // We have to convert previous per AL IsNode config to global + // So check if the global value exists + if (ini.ValueExists("AirLink", "IsWllNode")) + { + AirLinkIsNode = ini.GetValue("AirLink", "IsWllNode", false); + } + else + { + AirLinkIsNode = ini.GetValue("AirLink", "In-IsNode", false) || ini.GetValue("AirLink", "Out-IsNode", false); + } AirLinkApiKey = ini.GetValue("AirLink", "WLv2ApiKey", ""); AirLinkApiSecret = ini.GetValue("AirLink", "WLv2ApiSecret", ""); AirLinkAutoUpdateIpAddress = ini.GetValue("AirLink", "AutoUpdateIpAddress", true); AirLinkInEnabled = ini.GetValue("AirLink", "In-Enabled", false); AirLinkInIPAddr = ini.GetValue("AirLink", "In-IPAddress", "0.0.0.0"); - AirLinkInIsNode = ini.GetValue("AirLink", "In-IsNode", false); AirLinkInStationId = ini.GetValue("AirLink", "In-WLStationId", -1); - if (AirLinkInStationId == -1 && AirLinkInIsNode) AirLinkInStationId = WllStationId; + if (AirLinkInStationId == -1 && AirLinkIsNode) AirLinkInStationId = WllStationId; AirLinkInHostName = ini.GetValue("AirLink", "In-Hostname", ""); AirLinkOutEnabled = ini.GetValue("AirLink", "Out-Enabled", false); AirLinkOutIPAddr = ini.GetValue("AirLink", "Out-IPAddress", "0.0.0.0"); - AirLinkOutIsNode = ini.GetValue("AirLink", "Out-IsNode", false); AirLinkOutStationId = ini.GetValue("AirLink", "Out-WLStationId", -1); - if (AirLinkOutStationId == -1 && AirLinkOutIsNode) AirLinkOutStationId = WllStationId; + if (AirLinkOutStationId == -1 && AirLinkIsNode) AirLinkOutStationId = WllStationId; AirLinkOutHostName = ini.GetValue("AirLink", "Out-Hostname", ""); airQualityIndex = ini.GetValue("AirLink", "AQIformula", 0); @@ -3822,7 +3753,6 @@ private void ReadIniFile() FtpPassword = ini.GetValue("FTP site", "Password", ""); FtpDirectory = ini.GetValue("FTP site", "Directory", ""); - WebAutoUpdate = ini.GetValue("FTP site", "AutoUpdate", false); ActiveFTPMode = ini.GetValue("FTP site", "ActiveFTP", false); Sslftp = (FtpProtocols)ini.GetValue("FTP site", "Sslftp", 0); // BUILD 3092 - added alternate SFTP authenication options @@ -3843,23 +3773,71 @@ private void ReadIniFile() FTPlogging = ini.GetValue("FTP site", "FTPlogging", false); RealtimeEnabled = ini.GetValue("FTP site", "EnableRealtime", false); RealtimeFTPEnabled = ini.GetValue("FTP site", "RealtimeFTPEnabled", false); - RealtimeTxtFTP = ini.GetValue("FTP site", "RealtimeTxtFTP", false); - RealtimeGaugesTxtFTP = ini.GetValue("FTP site", "RealtimeGaugesTxtFTP", false); + + RealtimeFiles[0].Create = ini.GetValue("FTP site", "RealtimeTxtCreate", false); + RealtimeFiles[0].FTP = RealtimeFiles[0].Create && ini.GetValue("FTP site", "RealtimeTxtFTP", false); + RealtimeFiles[1].Create = ini.GetValue("FTP site", "RealtimeGaugesTxtCreate", false); + RealtimeFiles[1].FTP = RealtimeFiles[1].Create && ini.GetValue("FTP site", "RealtimeGaugesTxtFTP", false); + RealtimeInterval = ini.GetValue("FTP site", "RealtimeInterval", 30000); if (RealtimeInterval < 1) { RealtimeInterval = 1; } //RealtimeTimer.Change(0,RealtimeInterval); + + WebAutoUpdate = ini.GetValue("FTP site", "AutoUpdate", false); + // Have to allow for upgrade, set interval enabled to old WebAutoUpdate + if (ini.ValueExists("FTP site", "IntervalEnabled")) + { + WebIntervalEnabled = ini.GetValue("FTP site", "IntervalEnabled", false); + } + else + { + WebIntervalEnabled = WebAutoUpdate; + } + UpdateInterval = ini.GetValue("FTP site", "UpdateInterval", DefaultWebUpdateInterval); if (UpdateInterval<1) { UpdateInterval = 1; } SynchronisedWebUpdate = (60 % UpdateInterval == 0); - IncludeStandardFiles = ini.GetValue("FTP site", "IncludeSTD", true); - IncludeGraphDataFiles = ini.GetValue("FTP site", "IncludeGraphDataFiles", true); + + var IncludeStandardFiles = false; + if (ini.ValueExists("FTP site", "IncludeSTD")) + { + IncludeStandardFiles = ini.GetValue("FTP site", "IncludeSTD", false); + } + for (var i = 0; i < StdWebFiles.Length; i++) + { + var keyNameCreate = "Create-" + StdWebFiles[i].LocalFileName.Split('.')[0]; + var keyNameFTP = "Ftp-" + StdWebFiles[i].LocalFileName.Split('.')[0]; + StdWebFiles[i].Create = ini.GetValue("FTP site", keyNameCreate, IncludeStandardFiles); + StdWebFiles[i].FTP = ini.GetValue("FTP site", keyNameFTP, IncludeStandardFiles); + } + + var IncludeGraphDataFiles = false; + if (ini.ValueExists("FTP site", "IncludeGraphDataFiles")) + { + IncludeGraphDataFiles = ini.GetValue("FTP site", "IncludeGraphDataFiles", true); + } + for (var i = 0; i < GraphDataFiles.Length; i++) + { + var keyNameCreate = "Create-" + GraphDataFiles[i].LocalFileName.Split('.')[0]; + var keyNameFTP = "Ftp-" + GraphDataFiles[i].LocalFileName.Split('.')[0]; + GraphDataFiles[i].Create = ini.GetValue("FTP site", keyNameCreate, IncludeGraphDataFiles); + GraphDataFiles[i].FTP = ini.GetValue("FTP site", keyNameFTP, IncludeGraphDataFiles); + } + for (var i = 0; i < GraphDataEodFiles.Length; i++) + { + var keyNameCreate = "Create-" + GraphDataEodFiles[i].LocalFileName.Split('.')[0]; + var keyNameFTP = "Ftp-" + GraphDataEodFiles[i].LocalFileName.Split('.')[0]; + GraphDataEodFiles[i].Create = ini.GetValue("FTP site", keyNameCreate, IncludeGraphDataFiles); + GraphDataEodFiles[i].FTP = ini.GetValue("FTP site", keyNameFTP, IncludeGraphDataFiles); + } + IncludeMoonImage = ini.GetValue("FTP site", "IncludeMoonImage", false); FTPRename = ini.GetValue("FTP site", "FTPRename", false); UTF8encode = ini.GetValue("FTP site", "UTF8encode", true); DeleteBeforeUpload = ini.GetValue("FTP site", "DeleteBeforeUpload", false); - MaxFTPconnectRetries = ini.GetValue("FTP site", "MaxFTPconnectRetries", 3); + //MaxFTPconnectRetries = ini.GetValue("FTP site", "MaxFTPconnectRetries", 3); for (int i = 0; i < numextrafiles; i++) { @@ -3903,6 +3881,9 @@ private void ReadIniFile() GraphOptions.UVVisible = ini.GetValue("Graphs", "UVVisible", true); GraphOptions.SolarVisible = ini.GetValue("Graphs", "SolarVisible", true); GraphOptions.SunshineVisible = ini.GetValue("Graphs", "SunshineVisible", true); + GraphOptions.DailyAvgTempVisible = ini.GetValue("Graphs", "DailyAvgTempVisible", true); + GraphOptions.DailyMaxTempVisible = ini.GetValue("Graphs", "DailyMaxTempVisible", true); + GraphOptions.DailyMinTempVisible = ini.GetValue("Graphs", "DailyMinTempVisible", true); Wund.ID = ini.GetValue("Wunderground", "ID", ""); @@ -4218,47 +4199,47 @@ private void ReadIniFile() NOAAheatingthreshold = ini.GetValue("NOAA", "HeatingThreshold", -1000.0); if (NOAAheatingthreshold < -999) { - NOAAheatingthreshold = TempUnit == 0 ? 18.3 : 65; + NOAAheatingthreshold = Units.Temp == 0 ? 18.3 : 65; } NOAAcoolingthreshold = ini.GetValue("NOAA", "CoolingThreshold", -1000.0); if (NOAAcoolingthreshold < -999) { - NOAAcoolingthreshold = TempUnit == 0 ? 18.3 : 65; + NOAAcoolingthreshold = Units.Temp == 0 ? 18.3 : 65; } NOAAmaxtempcomp1 = ini.GetValue("NOAA", "MaxTempComp1", -1000.0); if (NOAAmaxtempcomp1 < -999) { - NOAAmaxtempcomp1 = TempUnit == 0 ? 27 : 80; + NOAAmaxtempcomp1 = Units.Temp == 0 ? 27 : 80; } NOAAmaxtempcomp2 = ini.GetValue("NOAA", "MaxTempComp2", -1000.0); if (NOAAmaxtempcomp2 < -999) { - NOAAmaxtempcomp2 = TempUnit == 0 ? 0 : 32; + NOAAmaxtempcomp2 = Units.Temp == 0 ? 0 : 32; } NOAAmintempcomp1 = ini.GetValue("NOAA", "MinTempComp1", -1000.0); if (NOAAmintempcomp1 < -999) { - NOAAmintempcomp1 = TempUnit == 0 ? 0 : 32; + NOAAmintempcomp1 = Units.Temp == 0 ? 0 : 32; } NOAAmintempcomp2 = ini.GetValue("NOAA", "MinTempComp2", -1000.0); if (NOAAmintempcomp2 < -999) { - NOAAmintempcomp2 = TempUnit == 0 ? -18 : 0; + NOAAmintempcomp2 = Units.Temp == 0 ? -18 : 0; } NOAAraincomp1 = ini.GetValue("NOAA", "RainComp1", -1000.0); if (NOAAraincomp1 < -999) { - NOAAraincomp1 = RainUnit == 0 ? 0.2 : 0.01; + NOAAraincomp1 = Units.Rain == 0 ? 0.2 : 0.01; } NOAAraincomp2 = ini.GetValue("NOAA", "RainComp2", -1000.0); if (NOAAraincomp2 < -999) { - NOAAraincomp2 = RainUnit == 0 ? 2 : 0.1; + NOAAraincomp2 = Units.Rain == 0 ? 2 : 0.1; } NOAAraincomp3 = ini.GetValue("NOAA", "RainComp3", -1000.0); if (NOAAraincomp3 < -999) { - NOAAraincomp3 = RainUnit == 0 ? 20 : 1; + NOAAraincomp3 = Units.Rain == 0 ? 20 : 1; } NOAAAutoSave = ini.GetValue("NOAA", "AutoSave", false); @@ -4555,18 +4536,17 @@ internal void WriteIniFile() ini.SetValue("GW1000", "AutoUpdateIpAddress", Gw1000AutoUpdateIpAddress); // AirLink settings + ini.SetValue("AirLink", "IsWllNode", AirLinkIsNode); ini.SetValue("AirLink", "WLv2ApiKey", AirLinkApiKey); ini.SetValue("AirLink", "WLv2ApiSecret", AirLinkApiSecret); ini.SetValue("AirLink", "AutoUpdateIpAddress", AirLinkAutoUpdateIpAddress); ini.SetValue("AirLink", "In-Enabled", AirLinkInEnabled); ini.SetValue("AirLink", "In-IPAddress", AirLinkInIPAddr); - ini.SetValue("AirLink", "In-IsNode", AirLinkInIsNode); ini.SetValue("AirLink", "In-WLStationId", AirLinkInStationId); ini.SetValue("AirLink", "In-Hostname", AirLinkInHostName); ini.SetValue("AirLink", "Out-Enabled", AirLinkOutEnabled); ini.SetValue("AirLink", "Out-IPAddress", AirLinkOutIPAddr); - ini.SetValue("AirLink", "Out-IsNode", AirLinkOutIsNode); ini.SetValue("AirLink", "Out-WLStationId", AirLinkOutStationId); ini.SetValue("AirLink", "Out-Hostname", AirLinkOutHostName); ini.SetValue("AirLink", "AQIformula", airQualityIndex); @@ -4581,7 +4561,6 @@ internal void WriteIniFile() ini.SetValue("FTP site", "Directory", FtpDirectory); ini.SetValue("FTP site", "AutoUpdate", WebAutoUpdate); - ini.SetValue("FTP site", "ActiveFTP", ActiveFTPMode); ini.SetValue("FTP site", "Sslftp", (int)Sslftp); // BUILD 3092 - added alternate SFTP authenication options ini.SetValue("FTP site", "SshFtpAuthentication", SshftpAuthentication); @@ -4590,25 +4569,46 @@ internal void WriteIniFile() ini.SetValue("FTP site", "FTPlogging", FTPlogging); ini.SetValue("FTP site", "UTF8encode", UTF8encode); ini.SetValue("FTP site", "EnableRealtime", RealtimeEnabled); - ini.SetValue("FTP site", "RealtimeFTPEnabled", RealtimeFTPEnabled); - ini.SetValue("FTP site", "RealtimeTxtFTP", RealtimeTxtFTP); - ini.SetValue("FTP site", "RealtimeGaugesTxtFTP", RealtimeGaugesTxtFTP); ini.SetValue("FTP site", "RealtimeInterval", RealtimeInterval); + ini.SetValue("FTP site", "RealtimeFTPEnabled", RealtimeFTPEnabled); + ini.SetValue("FTP site", "RealtimeTxtCreate", RealtimeFiles[0].Create); + ini.SetValue("FTP site", "RealtimeTxtFTP", RealtimeFiles[0].FTP); + ini.SetValue("FTP site", "RealtimeGaugesTxtCreate", RealtimeFiles[1].Create); + ini.SetValue("FTP site", "RealtimeGaugesTxtFTP", RealtimeFiles[1].FTP); + + ini.SetValue("FTP site", "IntervalEnabled", WebIntervalEnabled); ini.SetValue("FTP site", "UpdateInterval", UpdateInterval); - ini.SetValue("FTP site", "IncludeSTD", IncludeStandardFiles); - ini.SetValue("FTP site", "IncludeGraphDataFiles", IncludeGraphDataFiles); + for (var i = 0; i < StdWebFiles.Length; i++) + { + var keyNameCreate = "Create-" + StdWebFiles[i].LocalFileName.Split('.')[0]; + var keyNameFTP = "Ftp-" + StdWebFiles[i].LocalFileName.Split('.')[0]; + ini.SetValue("FTP site", keyNameCreate, StdWebFiles[i].Create); + ini.SetValue("FTP site", keyNameFTP, StdWebFiles[i].FTP); + } + + for (var i = 0; i < GraphDataFiles.Length; i++) + { + var keyNameCreate = "Create-" + GraphDataFiles[i].LocalFileName.Split('.')[0]; + var keyNameFTP = "Ftp-" + GraphDataFiles[i].LocalFileName.Split('.')[0]; + ini.SetValue("FTP site", keyNameCreate, GraphDataFiles[i].Create); + ini.SetValue("FTP site", keyNameFTP, GraphDataFiles[i].FTP); + } + + for (var i = 0; i < GraphDataEodFiles.Length; i++) + { + var keyNameCreate = "Create-" + GraphDataEodFiles[i].LocalFileName.Split('.')[0]; + var keyNameFTP = "Ftp-" + GraphDataEodFiles[i].LocalFileName.Split('.')[0]; + ini.SetValue("FTP site", keyNameCreate, GraphDataEodFiles[i].Create); + ini.SetValue("FTP site", keyNameFTP, GraphDataEodFiles[i].FTP); + } + ini.SetValue("FTP site", "IncludeMoonImage", IncludeMoonImage); - //ini.SetValue("FTP site", "IncludeSTDImages", IncludeStandardImages); - //ini.SetValue("FTP site", "IncludeSolarChart", IncludeSolarChart); - //ini.SetValue("FTP site", "IncludeUVChart", IncludeUVChart); - //ini.SetValue("FTP site", "IncludeSunshineChart", IncludeSunshineChart); ini.SetValue("FTP site", "FTPRename", FTPRename); ini.SetValue("FTP site", "DeleteBeforeUpload", DeleteBeforeUpload); - //ini.SetValue("FTP site", "ResizeGraphs", ResizeGraphs); - //ini.SetValue("FTP site", "GraphHeight", GraphHeight); - //ini.SetValue("FTP site", "GraphWidth", GraphWidth); - //ini.SetValue("FTP site", "ImageFolder", ImageFolder); - //ini.SetValue("FTP site", "ImageCopyRealtime", ImageCopyRealtime); + ini.SetValue("FTP site", "ActiveFTP", ActiveFTPMode); + ini.SetValue("FTP site", "DisableEPSV", DisableFtpsEPSV); + ini.SetValue("FTP site", "DisableFtpsExplicit", DisableFtpsExplicit); + for (int i = 0; i < numextrafiles; i++) { @@ -4959,6 +4959,9 @@ internal void WriteIniFile() ini.SetValue("Graphs", "UVVisible", GraphOptions.UVVisible); ini.SetValue("Graphs", "SolarVisible", GraphOptions.SolarVisible); ini.SetValue("Graphs", "SunshineVisible", GraphOptions.SunshineVisible); + ini.SetValue("Graphs", "DailyAvgTempVisible", GraphOptions.DailyAvgTempVisible); + ini.SetValue("Graphs", "DailyMaxTempVisible", GraphOptions.DailyMaxTempVisible); + ini.SetValue("Graphs", "DailyMinTempVisible", GraphOptions.DailyMinTempVisible); ini.SetValue("MySQL", "Host", MySqlHost); ini.SetValue("MySQL", "Port", MySqlPort); @@ -5354,7 +5357,7 @@ private void ReadStringsFile() public TExtraFiles[] ExtraFiles = new TExtraFiles[numextrafiles]; - public int MaxFTPconnectRetries { get; set; } + //public int MaxFTPconnectRetries { get; set; } public bool DeleteBeforeUpload { get; set; } @@ -5380,6 +5383,8 @@ private void ReadStringsFile() public bool FTPlogging { get; set; } + public bool WebIntervalEnabled { get; set; } + public bool WebAutoUpdate { get; set; } public string FtpDirectory { get; set; } @@ -5392,8 +5397,6 @@ private void ReadStringsFile() public string FtpHostname { get; set; } - public bool CreateWxnowTxt { get; set; } - public int WMR200TempChannel { get; set; } public int WMR928TempChannel { get; set; } @@ -5409,9 +5412,9 @@ private void ReadStringsFile() public bool AirLinkInEnabled { get; set; } public bool AirLinkOutEnabled { get; set; } - public bool solar_logging { get; set; } + //public bool solar_logging { get; set; } - public bool special_logging { get; set; } + //public bool special_logging { get; set; } public bool RG11DTRmode2 { get; set; } @@ -5501,9 +5504,6 @@ private void ReadStringsFile() public const int numextrafiles = 99; public const int numOfSelectaChartSeries = 6; - public int RainUnit { get; set; } - - //public bool WS2300Sync { get; set; } public bool ErrorLogSpikeRemoval { get; set; } @@ -5532,8 +5532,6 @@ private void ReadStringsFile() public string LatTxt { get; set; } - public int TempUnit { get; set; } - public bool AltitudeInFeet { get; set; } public string StationModel { get; set; } @@ -5599,11 +5597,10 @@ private void ReadStringsFile() public bool[] WllExtraHumTx = { false, false, false, false, false, false, false, false }; // WeatherLink Live transmitter Ids and indexes - public bool AirLinkInIsNode; + public bool AirLinkIsNode; public string AirLinkApiKey; public string AirLinkApiSecret; public int AirLinkInStationId; - public bool AirLinkOutIsNode; public int AirLinkOutStationId; public bool AirLinkAutoUpdateIpAddress = true; @@ -5640,34 +5637,22 @@ private void ReadStringsFile() public DateTime LatestErrorTS = DateTime.MinValue; //public DateTime defaultRecordTS = new DateTime(2000, 1, 1, 0, 0, 0); public DateTime defaultRecordTS = DateTime.MinValue; - public string wxnowfile = "wxnow.txt"; - private readonly string IndexTFile; - private readonly string TodayTFile; - private readonly string YesterdayTFile; - private readonly string RecordTFile; - private readonly string MonthlyRecordTFile; - private readonly string TrendsTFile; - private readonly string HistoricTFile; - private readonly string SelectaChartTFile; - private readonly string ThisMonthTFile; - private readonly string ThisYearTFile; - private readonly string GaugesTFile; + public string WxnowFile = "wxnow.txt"; private readonly string RealtimeFile = "realtime.txt"; - private readonly string RealtimeGaugesTxtTFile; - private readonly string RealtimeGaugesTxtFile; private readonly string TwitterTxtFile; - public bool IncludeStandardFiles = true; - public bool IncludeGraphDataFiles; public bool IncludeMoonImage; private readonly FtpClient RealtimeFTP = new FtpClient(); private SftpClient RealtimeSSH; private volatile bool RealtimeFtpInProgress; private volatile bool RealtimeCopyInProgress; private byte RealtimeCycleCounter; - public readonly string[] localGraphdataFiles; - private readonly string[] remoteGraphdataFiles; - public readonly string[] localDailyGraphdataFiles; - private readonly string[] remoteDailyGraphdataFiles; + + public FileGenerationFtpOptions[] StdWebFiles; + public FileGenerationFtpOptions[] RealtimeFiles; + public FileGenerationFtpOptions[] GraphDataFiles; + public FileGenerationFtpOptions[] GraphDataEodFiles; + + public string exceptional = "Exceptional Weather"; // private WebSocketServer wsServer; public string[] WMR200ExtraChannelCaptions = new string[11]; @@ -6916,23 +6901,20 @@ public void DoHTMLFiles() CreateRealtimeFile(999); } - //TODO: Sort out the mess of options for generating and FTPing all the standard files. - //if (IncludeStandardFiles) - //{ - LogDebugMessage("Creating standard HTML files"); - for (var i = 0; i < localWebTextFiles.Length; i++) + LogDebugMessage("Creating standard web files"); + for (var i = 0; i < StdWebFiles.Length; i++) + { + if (StdWebFiles[i].Create && !string.IsNullOrWhiteSpace(StdWebFiles[i].TemplateFileName)) { - ProcessTemplateFile(localWebTemplateFiles[i], localWebTextFiles[i], tokenParser); + var destFile = StdWebFiles[i].LocalPath + StdWebFiles[i].LocalFileName; + ProcessTemplateFile(StdWebFiles[i].TemplateFileName, destFile, tokenParser); } - LogDebugMessage("Done creating standard HTML files"); - //} + } + LogDebugMessage("Done creating standard Data file"); - //if (IncludeGraphDataFiles) - //{ - LogDebugMessage("Creating graph data files"); - station.CreateGraphDataFiles(); - LogDebugMessage("Done creating graph data files"); - //} + LogDebugMessage("Creating graph data files"); + station.CreateGraphDataFiles(); + LogDebugMessage("Done creating graph data files"); //LogDebugMessage("Creating extra files"); // handle any extra files @@ -7044,6 +7026,13 @@ public void DoHTMLFiles() public void DoFTPLogin() { + var remotePath = ""; + + if (FtpDirectory.Length > 0) + { + remotePath = (FtpDirectory.EndsWith("/") ? FtpDirectory : FtpDirectory + "/"); + } + if (Sslftp == FtpProtocols.SFTP) { // BUILD 3092 - added alternate SFTP authenication options @@ -7086,7 +7075,6 @@ public void DoFTPLogin() if (conn.IsConnected) { - string remotePath = (FtpDirectory.EndsWith("/") ? FtpDirectory : FtpDirectory + "/"); if (NOAANeedFTP) { try @@ -7179,68 +7167,75 @@ public void DoFTPLogin() LogFtpDebugMessage("SFTP[Int]: Done uploading extra files"); // standard files - if (IncludeStandardFiles) + LogFtpDebugMessage("SFTP[Int]: Uploading standard web files"); + for (var i = 0; i < StdWebFiles.Length; i++) { - LogFtpDebugMessage("SFTP[Int]: Uploading standard files"); - for (int i = 0; i < localWebTextFiles.Length; i++) + if (StdWebFiles[i].FTP && StdWebFiles[i].FtpRequired) + { + try { - var uploadfile = localWebTextFiles[i]; - var remotefile = remotePath + remoteWebTextFiles[i]; - - try - { - UploadFile(conn, uploadfile, remotefile, -1); - } - catch (Exception e) - { - LogFtpMessage($"SFTP[Int]: Error uploading standard web file [{uploadfile}]"); - LogFtpMessage($"SFTP[Int]: Error = {e.Message}"); - } + var localFile = StdWebFiles[i].LocalPath + StdWebFiles[i].LocalFileName; + var remotefile = remotePath + StdWebFiles[i].RemoteFileName; + UploadFile(conn, localFile, remotefile, -1); + } + catch (Exception e) + { + LogFtpMessage($"SFTP[Int]: Error uploading standard data file [{StdWebFiles[i].LocalFileName}]"); + LogFtpMessage($"SFTP[Int]: Error = {e}"); } - LogFtpDebugMessage("SFTP[Int]: Done uploading standard files"); + } } + LogFtpDebugMessage("SFTP[Int]: Done uploading standard web files"); - if (IncludeGraphDataFiles) + LogFtpDebugMessage("SFTP[Int]: Uploading graph data files"); + + for (int i = 0; i < GraphDataFiles.Length; i++) { - LogFtpDebugMessage("SFTP[Int]: Uploading graph data files"); - for (int i = 0; i < localGraphdataFiles.Length; i++) + if (GraphDataFiles[i].FTP && GraphDataFiles[i].FtpRequired) { - var uploadfile = localGraphdataFiles[i]; - var remotefile = remotePath + remoteGraphdataFiles[i]; + var uploadfile = GraphDataFiles[i].LocalPath + GraphDataFiles[i].LocalFileName; + var remotefile = remotePath + GraphDataFiles[i].RemoteFileName; try { UploadFile(conn, uploadfile, remotefile, -1); + // The config files only need uploading once per change + if (GraphDataFiles[i].LocalFileName == "availabledata.json" || + GraphDataFiles[i].LocalFileName == "graphconfig.json") + { + GraphDataFiles[i].FtpRequired = false; + } } catch (Exception e) { LogFtpMessage($"SFTP[Int]: Error uploading graph data file [{uploadfile}]"); - LogFtpMessage($"SFTP[Int]: Error = {e.Message}"); + LogFtpMessage($"SFTP[Int]: Error = {e}"); } } - LogFtpDebugMessage("SFTP[Int]: Done uploading graph data files"); + } + LogFtpDebugMessage("SFTP[Int]: Done uploading graph data files"); - if (DailyGraphDataFilesNeedFTP) + LogFtpMessage("SFTP[Int]: Uploading daily graph data files"); + for (int i = 0; i < GraphDataEodFiles.Length; i++) + { + if (GraphDataEodFiles[i].FTP && GraphDataEodFiles[i].FtpRequired) { - LogFtpMessage("SFTP[Int]: Uploading daily graph data files"); - for (int i = 0; i < localDailyGraphdataFiles.Length; i++) + var uploadfile = GraphDataEodFiles[i].LocalPath + GraphDataEodFiles[i].LocalFileName; + var remotefile = remotePath + GraphDataEodFiles[i].RemoteFileName; + try { - var uploadfile = localDailyGraphdataFiles[i]; - var remotefile = remotePath + remoteDailyGraphdataFiles[i]; - try - { - UploadFile(conn, uploadfile, remotefile, -1); - } - catch (Exception e) - { - LogFtpMessage($"SFTP[Int]: Error uploading daily graph data file [{uploadfile}]"); - LogFtpMessage($"SFTP[Int]: Error = {e.Message}"); - } + UploadFile(conn, uploadfile, remotefile, -1); + // Uploaded OK, reset the upload required flag + GraphDataEodFiles[i].FtpRequired = false; + } + catch (Exception e) + { + LogFtpMessage($"SFTP[Int]: Error uploading daily graph data file [{uploadfile}]"); + LogFtpMessage($"SFTP[Int]: Error = {e}"); } - DailyGraphDataFilesNeedFTP = false; - LogFtpMessage("SFTP[Int]: Done uploading daily graph data files"); } } + LogFtpMessage("SFTP[Int]: Done uploading daily graph data files"); if (IncludeMoonImage && MoonImageReady) { @@ -7311,12 +7306,6 @@ public void DoFTPLogin() if (conn.IsConnected) { - string remotePath = ""; - if (FtpDirectory.Length > 0) - { - remotePath = (FtpDirectory.EndsWith("/") ? FtpDirectory : FtpDirectory + "/"); - } - if (NOAANeedFTP) { try @@ -7413,69 +7402,65 @@ public void DoFTPLogin() EODfilesNeedFTP = false; } // standard files - if (IncludeStandardFiles) + LogFtpDebugMessage("FTP[Int]: Uploading standard Data file"); + for (int i = 0; i < StdWebFiles.Length; i++) { - string uploadfile; - LogFtpDebugMessage("FTP[Int]: Uploading standard files"); - for (int i = 0; i < localWebTextFiles.Length; i++) + if (StdWebFiles[i].FTP && StdWebFiles[i].FtpRequired) { - uploadfile = localWebTextFiles[i]; - var remotefile = remotePath + remoteWebTextFiles[i]; - try { - UploadFile(conn, uploadfile, remotefile); + var localfile = StdWebFiles[i].LocalPath + StdWebFiles[i].LocalFileName; + UploadFile(conn, localfile, remotePath + StdWebFiles[i].RemoteFileName); } catch (Exception e) { - LogFtpMessage($"FTP[Int]: Error uploading file {uploadfile}: {e.Message}"); + LogFtpMessage($"FTP[Int]: Error uploading file {StdWebFiles[i].LocalFileName}: {e}"); } } - //LogDebugMessage("Done uploading standard files"); } + LogFtpMessage("Done uploading standard Data file"); - if (IncludeGraphDataFiles) + LogFtpDebugMessage("FTP[Int]: Uploading graph data files"); + for (int i = 0; i < GraphDataFiles.Length; i++) { - LogFtpDebugMessage("FTP[Int]: Uploading graph data files"); - for (int i = 0; i < localGraphdataFiles.Length; i++) + if (GraphDataFiles[i].FTP && GraphDataFiles[i].FtpRequired) { - var uploadfile = localGraphdataFiles[i]; - var remotefile = remotePath + remoteGraphdataFiles[i]; - try { - UploadFile(conn, uploadfile, remotefile); + var localfile = GraphDataFiles[i].LocalPath + GraphDataFiles[i].LocalFileName; + var remotefile = remotePath + GraphDataFiles[i].RemoteFileName; + UploadFile(conn, localfile, remotefile); } catch (Exception e) { - LogFtpMessage($"FTP[Int]: Error uploading graph data file [{uploadfile}]"); - LogFtpMessage($"FTP[Int]: Error = {e.Message}"); + LogFtpMessage($"FTP[Int]: Error uploading graph data file [{GraphDataFiles[i].LocalFileName}]"); + LogFtpMessage($"FTP[Int]: Error = {e}"); } } - //LogDebugMessage("Done uploading graph data files"); + } + LogFtpMessage("Done uploading graph data files"); - if (DailyGraphDataFilesNeedFTP) + LogFtpMessage("FTP[Int]: Uploading daily graph data files"); + for (int i = 0; i < GraphDataEodFiles.Length; i++) + { + if (GraphDataEodFiles[i].FTP && GraphDataEodFiles[i].FtpRequired) { - LogFtpMessage("FTP[Int]: Uploading daily graph data files"); - for (int i = 0; i < localDailyGraphdataFiles.Length; i++) + var localfile = GraphDataEodFiles[i].LocalPath + GraphDataEodFiles[i].LocalFileName; + var remotefile = remotePath + GraphDataEodFiles[i].RemoteFileName; + try { - var uploadfile = localDailyGraphdataFiles[i]; - var remotefile = remotePath + remoteDailyGraphdataFiles[i]; - - try - { - UploadFile(conn, uploadfile, remotefile); - } - catch (Exception e) - { - LogFtpMessage($"FTP[Int]: Error uploading daily graph data file [{uploadfile}]"); - LogFtpMessage($"FTP[Int]: Error = {e.Message}"); - } + UploadFile(conn, localfile, remotefile, -1); + // Uploaded OK, reset the upload required flag + GraphDataEodFiles[i].FtpRequired = false; + } + catch (Exception e) + { + LogFtpMessage($"SFTP[Int]: Error uploading daily graph data file [{GraphDataEodFiles[i].LocalFileName}]"); + LogFtpMessage($"SFTP[Int]: Error = {e}"); } - LogFtpMessage("FTP[Int]: Done uploading daily graph data files"); - DailyGraphDataFilesNeedFTP = false; } } + LogFtpMessage("FTP[Int]: Done uploading daily graph data files"); if (IncludeMoonImage && MoonImageReady) { @@ -7778,6 +7763,13 @@ 57 420 Current theoretical max solar radiation 58 1 Is sunny? 59 8.4 Feels Like temperature */ + + // Does the user want to create the realtime.txt file? + if (!RealtimeFiles[0].Create) + { + return; + } + var filename = AppDir + RealtimeFile; DateTime timestamp = DateTime.Now; @@ -7800,10 +7792,10 @@ 59 8.4 Feels Like temperature file.Write(station.Pressure.ToString(PressFormat, InvC) + ' '); // 11 file.Write(station.CompassPoint(station.Bearing) + ' '); // 12 file.Write(Beaufort(station.WindAverage) + ' '); // 13 - file.Write(Units.WindText + ' '); // 14 - file.Write(Units.TempText[1].ToString() + ' '); // 15 - file.Write(Units.PressText + ' '); // 16 - file.Write(Units.RainText + ' '); // 17 + file.Write(Units.WindText + ' '); // 14 + file.Write(Units.TempText[1].ToString() + ' '); // 15 + file.Write(Units.PressText + ' '); // 16 + file.Write(Units.RainText + ' '); // 17 file.Write(station.WindRunToday.ToString(WindRunFormat, InvC) + ' '); // 18 if (station.presstrendval > 0) file.Write('+' + station.presstrendval.ToString(PressFormat, InvC) + ' '); // 19 @@ -8016,21 +8008,22 @@ public void StartTimersAndSensors() station.StartMinuteTimer(); LogMessage($"Data logging interval = {DataLogInterval} ({logints[DataLogInterval]} mins)"); - if (RealtimeFTPEnabled) + + if (RealtimeEnabled) { - LogConsoleMessage("Connecting real time FTP"); - if (Sslftp == FtpProtocols.SFTP) - { - RealtimeSSHLogin(RealtimeCycleCounter++); - } - else + if (RealtimeFTPEnabled) { - RealtimeFTPLogin(RealtimeCycleCounter++); + LogConsoleMessage("Connecting real time FTP"); + if (Sslftp == FtpProtocols.SFTP) + { + RealtimeSSHLogin(RealtimeCycleCounter++); + } + else + { + RealtimeFTPLogin(RealtimeCycleCounter++); + } } - } - if (RealtimeEnabled) - { LogMessage("Starting Realtime timer, interval = " + RealtimeInterval / 1000 + " seconds"); } else @@ -8204,7 +8197,7 @@ public void StartTimersAndSensors() APRStimer.Enabled = APRS.Enabled && !APRS.SynchronisedUpdate; WebTimer.Interval = UpdateInterval * 60 * 1000; // mins to millisecs - WebTimer.Enabled = WebAutoUpdate && !SynchronisedWebUpdate; + WebTimer.Enabled = WebIntervalEnabled && !SynchronisedWebUpdate; AwekasTimer.Enabled = AWEKAS.Enabled && !AWEKAS.SynchronisedUpdate; @@ -8456,6 +8449,23 @@ private void MySqlCatchup() MySqlList.Clear(); } + public void RealtimeFTPDisconnect() + { + try + { + if (Sslftp == FtpProtocols.SFTP) + { + RealtimeSSH.Disconnect(); + } + else + { + RealtimeFTP.Disconnect(); + } + LogDebugMessage("Disconnected Realtime FTP session"); + } + catch { } + } + private void RealtimeFTPLogin(uint cycle) { //RealtimeTimer.Enabled = false; @@ -9249,6 +9259,23 @@ public class StationOptions public int PeakGustMinutes { get; set; } } + public class FileGenerationFtpOptions + { + public string TemplateFileName { get; set; } + public string LocalFileName { get; set; } + public string LocalPath { get; set; } + public string RemoteFileName { get; set; } + public bool Create { get; set; } + public bool FTP { get; set; } + public bool FtpRequired { get; set; } + public bool CreateRequired { get; set; } + public FileGenerationFtpOptions() + { + CreateRequired = true; + FtpRequired = true; + } + } + public class DavisOptions { public bool ForceVPBarUpdate { get; set; } @@ -9310,6 +9337,9 @@ public class GraphOptions public bool UVVisible { get; set; } public bool SolarVisible { get; set; } public bool SunshineVisible { get; set; } + public bool DailyMaxTempVisible { get; set; } + public bool DailyAvgTempVisible { get; set; } + public bool DailyMinTempVisible { get; set; } } public class SelectaChartOptions diff --git a/CumulusMX/DataEditor.cs b/CumulusMX/DataEditor.cs index fcd2e4e6..d9af8492 100644 --- a/CumulusMX/DataEditor.cs +++ b/CumulusMX/DataEditor.cs @@ -12,19 +12,28 @@ namespace CumulusMX { internal class DataEditor { - private readonly WeatherStation station; - private readonly Cumulus cumulus; - private readonly WebTags webtags; + private WeatherStation station; + private Cumulus cumulus; + private WebTags webtags; private readonly List hourRainLog = new List(); - internal DataEditor(Cumulus cumulus, WeatherStation station, WebTags webtags) + //internal DataEditor(Cumulus cumulus, WeatherStation station, WebTags webtags) + internal DataEditor(Cumulus cumulus) { - this.station = station; + //this.station = station; this.cumulus = cumulus; - this.webtags = webtags; } + internal void SetStation(WeatherStation station) + { + this.station = station; + } + + internal void SetWebTags(WebTags webtags) + { + this.webtags = webtags; + } //internal string EditRainToday(HttpListenerContext context) internal string EditRainToday(IHttpContext context) { diff --git a/CumulusMX/DavisAirLink.cs b/CumulusMX/DavisAirLink.cs index 15db8298..ab676cef 100644 --- a/CumulusMX/DavisAirLink.cs +++ b/CumulusMX/DavisAirLink.cs @@ -61,7 +61,7 @@ public DavisAirLink(Cumulus cumulus, bool indoor, WeatherStation station) // Easist to see if we are a node of a WLL station standalone = !( cumulus.StationType == StationTypes.WLL && - (this.indoor ? cumulus.AirLinkInIsNode : cumulus.AirLinkOutIsNode) && + cumulus.AirLinkIsNode && !string.IsNullOrEmpty(cumulus.WllApiKey) && !string.IsNullOrEmpty(cumulus.WllApiSecret) && !(cumulus.WllStationId < 10) diff --git a/CumulusMX/DavisStation.cs b/CumulusMX/DavisStation.cs index 50f4d8bd..cf3d52e5 100644 --- a/CumulusMX/DavisStation.cs +++ b/CumulusMX/DavisStation.cs @@ -3733,7 +3733,7 @@ private double ConvertRainClicksToUser(double clicks) default: // Rain gauge type not configured, assume it is the same as the station units - return cumulus.RainUnit == 0 ? clicks * 0.2 : clicks * 0.01; + return cumulus.Units.Rain == 0 ? clicks * 0.2 : clicks * 0.01; } } diff --git a/CumulusMX/DavisWllStation.cs b/CumulusMX/DavisWllStation.cs index 059e014b..37d92350 100644 --- a/CumulusMX/DavisWllStation.cs +++ b/CumulusMX/DavisWllStation.cs @@ -237,9 +237,11 @@ public override void Start() { try { + var jsonBtye = udpClient.Receive(ref from); + var jsonStr = Encoding.UTF8.GetString(jsonBtye); if (!stop) // we may be waiting for a broadcast when a shutdown is started { - DecodeBroadcast(Encoding.UTF8.GetString(udpClient.Receive(ref from))); + DecodeBroadcast(jsonStr); } } catch (SocketException exp) @@ -452,7 +454,6 @@ private void DecodeBroadcast(string broadcastJson) if (broadcastJson.StartsWith("{\"did\":")) { var json = broadcastJson.FromJson(); - // The WLL sends the timestamp in Unix ticks, and in UTC // rather than rely on the WLL clock being correct, we will use our local time var dateTime = DateTime.Now; @@ -551,6 +552,8 @@ private void DecodeBroadcast(string broadcastJson) } } + json = null; + UpdateStatusPanel(DateTime.Now); UpdateMQTT(); @@ -1184,7 +1187,7 @@ private double ConvertRainClicksToUser(double clicks, int size) // One click is normally either 0.01 inches or 0.2 mm // Try the setting in Cumulus.ini // Rain gauge type not configured, assume from units - case -1 when cumulus.RainUnit == 0: + case -1 when cumulus.Units.Rain == 0: return clicks * 0.2; case -1: return clicks * 0.01; diff --git a/CumulusMX/ExtraSensorSettings.cs b/CumulusMX/ExtraSensorSettings.cs index 99403481..ffb78f0a 100644 --- a/CumulusMX/ExtraSensorSettings.cs +++ b/CumulusMX/ExtraSensorSettings.cs @@ -25,7 +25,6 @@ public string GetExtraSensorAlpacaFormData() { ipAddress = cumulus.AirLinkInIPAddr, hostname = cumulus.AirLinkInHostName, - isNode = cumulus.AirLinkInIsNode, stationId = cumulus.AirLinkInStationId }; @@ -33,12 +32,12 @@ public string GetExtraSensorAlpacaFormData() { ipAddress = cumulus.AirLinkOutIPAddr, hostname = cumulus.AirLinkOutHostName, - isNode = cumulus.AirLinkOutIsNode, stationId = cumulus.AirLinkOutStationId }; var airlink = new JsonExtraSensorAirLinkSettings() { + isNode = cumulus.AirLinkIsNode, apiKey = cumulus.AirLinkApiKey, apiSecret = cumulus.AirLinkApiSecret, autoUpdateIp = cumulus.AirLinkAutoUpdateIpAddress, @@ -77,10 +76,15 @@ public string GetExtraSensorAlpacaFormData() port2 = rg11port2 }; - var data = new JsonExtraSensorSettings() + var aq = new JsonExtraSensorAirQuality() { primaryaqsensor = cumulus.StationOptions.PrimaryAqSensor, aqi = cumulus.airQualityIndex, + }; + + var data = new JsonExtraSensorSettings() + { + airquality = aq, airLink = airlink, blakeLarsen = bl, rg11 = rg11 @@ -109,8 +113,8 @@ public string UpdateExtraSensorConfig(IHttpContext context) // General settings try { - cumulus.StationOptions.PrimaryAqSensor = settings.primaryaqsensor; - cumulus.airQualityIndex = settings.aqi; + cumulus.StationOptions.PrimaryAqSensor = settings.airquality.primaryaqsensor; + cumulus.airQualityIndex = settings.airquality.aqi; } catch (Exception ex) { @@ -123,6 +127,7 @@ public string UpdateExtraSensorConfig(IHttpContext context) // AirLink settings try { + cumulus.AirLinkIsNode = settings.airLink.isNode; cumulus.AirLinkApiKey = settings.airLink.apiKey; cumulus.AirLinkApiSecret = settings.airLink.apiSecret; cumulus.AirLinkAutoUpdateIpAddress = settings.airLink.autoUpdateIp; @@ -130,11 +135,10 @@ public string UpdateExtraSensorConfig(IHttpContext context) cumulus.AirLinkInEnabled = settings.airLink.indoorenabled; if (cumulus.AirLinkInEnabled && settings.airLink.indoor != null) { - cumulus.AirLinkInIsNode = settings.airLink.indoor.isNode; cumulus.AirLinkInIPAddr = settings.airLink.indoor.ipAddress; cumulus.AirLinkInHostName = settings.airLink.indoor.hostname; cumulus.AirLinkInStationId = settings.airLink.indoor.stationId; - if (cumulus.AirLinkInStationId < 10 && cumulus.AirLinkInIsNode) + if (cumulus.AirLinkInStationId < 10 && cumulus.AirLinkIsNode) { cumulus.AirLinkInStationId = cumulus.WllStationId; } @@ -142,11 +146,10 @@ public string UpdateExtraSensorConfig(IHttpContext context) cumulus.AirLinkOutEnabled = settings.airLink.outdoorenabled; if (cumulus.AirLinkOutEnabled && settings.airLink.outdoor != null) { - cumulus.AirLinkOutIsNode = settings.airLink.outdoor.isNode; cumulus.AirLinkOutIPAddr = settings.airLink.outdoor.ipAddress; cumulus.AirLinkOutHostName = settings.airLink.outdoor.hostname; cumulus.AirLinkOutStationId = settings.airLink.outdoor.stationId; - if (cumulus.AirLinkOutStationId < 10 && cumulus.AirLinkOutIsNode) + if (cumulus.AirLinkOutStationId < 10 && cumulus.AirLinkIsNode) { cumulus.AirLinkOutStationId = cumulus.WllStationId; } @@ -240,16 +243,22 @@ public string GetExtraSensorAlpacaFormSchema() public class JsonExtraSensorSettings { - public int primaryaqsensor { get; set; } - public int aqi { get; set; } - + public JsonExtraSensorAirQuality airquality { get; set; } public JsonExtraSensorAirLinkSettings airLink { get; set; } public JsonExtraSensorBlakeLarsen blakeLarsen { get; set; } public JsonExtraSensorRG11 rg11 { get; set; } -} + } + + public class JsonExtraSensorAirQuality + { + public int primaryaqsensor { get; set; } + public int aqi { get; set; } + } + public class JsonExtraSensorAirLinkSettings { + public bool isNode { get; set; } public string apiKey { get; set; } public string apiSecret { get; set; } public bool autoUpdateIp { get; set; } @@ -263,7 +272,6 @@ public class JsonExtraSensorAirLinkDevice { public string ipAddress { get; set; } public string hostname { get; set; } - public bool isNode { get; set; } public int stationId { get; set; } } diff --git a/CumulusMX/IniFile.cs b/CumulusMX/IniFile.cs index e2c3b62e..c1cfc032 100644 --- a/CumulusMX/IniFile.cs +++ b/CumulusMX/IniFile.cs @@ -239,7 +239,31 @@ internal void SetValue(string SectionName, string Key, string Value) } } - // *** Encode byte array *** + internal bool ValueExists(string SectionName, string Key) + { + // *** Lazy loading *** + if (m_Lazy) + { + m_Lazy = false; + Refresh(); + } + + lock (m_Lock) + { + // *** Check if the section exists *** + Dictionary Section; + if (!m_Sections.TryGetValue(SectionName, out Section)) return false; + + // *** Check if the key exists *** + string Value; + if (Section.TryGetValue(Key, out Value)) + return true; + else + return false; + } + } + + // *** Encode byte array *** private string EncodeByteArray(byte[] Value) { if (Value == null) return null; diff --git a/CumulusMX/InternetSettings.cs b/CumulusMX/InternetSettings.cs index eb95df82..4c9b1bec 100644 --- a/CumulusMX/InternetSettings.cs +++ b/CumulusMX/InternetSettings.cs @@ -53,6 +53,17 @@ public string UpdateInternetConfig(IHttpContext context) cumulus.SshftpAuthentication = settings.website.sshAuth ?? string.Empty; cumulus.SshftpPskFile = settings.website.pskFile ?? string.Empty; cumulus.WebcamURL = settings.website.webcamurl ?? string.Empty; + + if (cumulus.Sslftp == Cumulus.FtpProtocols.FTP || cumulus.Sslftp == Cumulus.FtpProtocols.FTPS) { + cumulus.ActiveFTPMode = settings.website.advanced.activeftp; + cumulus.DisableFtpsEPSV = settings.website.advanced.disableftpsepsv; + } + + if (cumulus.Sslftp == Cumulus.FtpProtocols.FTPS) + { + cumulus.DisableFtpsExplicit = settings.website.advanced.disableftpsexplicit; + } + } catch (Exception ex) { @@ -65,26 +76,57 @@ public string UpdateInternetConfig(IHttpContext context) // web settings try { - cumulus.ActiveFTPMode = settings.websettings.activeftp; - cumulus.WebAutoUpdate = settings.websettings.autoupdate; - cumulus.RealtimeEnabled = settings.websettings.enablerealtime; - cumulus.RealtimeFTPEnabled = settings.websettings.enablerealtimeftp; - cumulus.RealtimeTxtFTP = settings.websettings.realtimetxtftp; - cumulus.RealtimeGaugesTxtFTP = settings.websettings.realtimegaugestxtftp; - cumulus.RealtimeInterval = settings.websettings.realtimeinterval * 1000; - cumulus.DeleteBeforeUpload = settings.websettings.ftpdelete; - cumulus.UpdateInterval = settings.websettings.ftpinterval; - cumulus.FTPRename = settings.websettings.ftprename; - cumulus.IncludeStandardFiles = settings.websettings.includestdfiles; - cumulus.IncludeGraphDataFiles = settings.websettings.includegraphdatafiles; - cumulus.UTF8encode = settings.websettings.utf8encode; - if (settings.websettings.ftplogging != cumulus.FTPlogging) + cumulus.DeleteBeforeUpload = settings.websettings.general.ftpdelete; + cumulus.FTPRename = settings.websettings.general.ftprename; + cumulus.UTF8encode = settings.websettings.general.utf8encode; + if (settings.websettings.general.ftplogging != cumulus.FTPlogging) { - cumulus.FTPlogging = settings.websettings.ftplogging; + cumulus.FTPlogging = settings.websettings.general.ftplogging; cumulus.SetFtpLogging(cumulus.FTPlogging); } + + cumulus.RealtimeEnabled = settings.websettings.realtime.enabled; + if (cumulus.RealtimeEnabled) + { + cumulus.RealtimeFTPEnabled = settings.websettings.realtime.enablerealtimeftp; + cumulus.RealtimeInterval = settings.websettings.realtime.realtimeinterval * 1000; + + for (var i = 0; i < cumulus.RealtimeFiles.Length; i++) + { + cumulus.RealtimeFiles[i].Create = settings.websettings.realtime.files[i].create; + cumulus.RealtimeFiles[i].FTP = settings.websettings.realtime.files[i].ftp; + } + } cumulus.RealtimeTimer.Enabled = cumulus.RealtimeEnabled; + if (!cumulus.RealtimeTimer.Enabled || !cumulus.RealtimeFTPEnabled) + { + cumulus.RealtimeFTPDisconnect(); + } + + cumulus.WebIntervalEnabled = settings.websettings.interval.enabled; + if (cumulus.WebIntervalEnabled) + { + cumulus.WebAutoUpdate = settings.websettings.interval.autoupdate; + cumulus.UpdateInterval = settings.websettings.interval.ftpinterval; + for (var i = 0; i < cumulus.StdWebFiles.Length; i++) + { + cumulus.StdWebFiles[i].Create = settings.websettings.interval.stdfiles.files[i].create; + cumulus.StdWebFiles[i].FTP = cumulus.StdWebFiles[i].Create && settings.websettings.interval.stdfiles.files[i].ftp; + } + + for (var i = 0; i < cumulus.GraphDataFiles.Length; i++) + { + cumulus.GraphDataFiles[i].Create = settings.websettings.interval.graphfiles.files[i].create; + cumulus.GraphDataFiles[i].FTP = settings.websettings.interval.graphfiles.files[i].ftp; + } + + for (var i = 0; i < cumulus.GraphDataEodFiles.Length; i++) + { + cumulus.GraphDataEodFiles[i].Create = settings.websettings.interval.graphfileseod.files[i].create; + cumulus.GraphDataEodFiles[i].FTP = settings.websettings.interval.graphfileseod.files[i].ftp; + } + } } catch (Exception ex) { @@ -508,6 +550,13 @@ public string UpdateInternetConfig(IHttpContext context) public string GetInternetAlpacaFormData() { + var websettingsadvanced = new JsonInternetSettingsWebsiteAdvanced() + { + activeftp = cumulus.ActiveFTPMode, + disableftpsepsv = cumulus.DisableFtpsEPSV, + disableftpsexplicit = cumulus.DisableFtpsExplicit + }; + // Build the settings data, convert to JSON, and return it var websitesettings = new JsonInternetSettingsWebsite() { @@ -520,27 +569,101 @@ public string GetInternetAlpacaFormData() username = cumulus.FtpUsername, sshAuth = cumulus.SshftpAuthentication, pskFile = cumulus.SshftpPskFile, - webcamurl = cumulus.WebcamURL + webcamurl = cumulus.WebcamURL, + advanced = websettingsadvanced }; - var websettings = new JsonInternetSettingsWebSettings() + var websettingsgeneral = new JsonInternetSettingsWebSettingsGeneral() { - activeftp = cumulus.ActiveFTPMode, - autoupdate = cumulus.WebAutoUpdate, - enablerealtime = cumulus.RealtimeEnabled, - enablerealtimeftp = cumulus.RealtimeFTPEnabled, - realtimetxtftp = cumulus.RealtimeTxtFTP, - realtimegaugestxtftp = cumulus.RealtimeGaugesTxtFTP, - realtimeinterval = cumulus.RealtimeInterval / 1000, ftpdelete = cumulus.DeleteBeforeUpload, - ftpinterval = cumulus.UpdateInterval, ftprename = cumulus.FTPRename, - includestdfiles = cumulus.IncludeStandardFiles, - includegraphdatafiles = cumulus.IncludeGraphDataFiles, utf8encode = cumulus.UTF8encode, ftplogging = cumulus.FTPlogging }; + var websettingsintervalstd = new JsonInternetSettingsWebSettingsIntervalFiles() + { + files = new JsonInternetSettingsFileSettings[cumulus.StdWebFiles.Length] + }; + + var websettingsintervalgraph = new JsonInternetSettingsWebSettingsIntervalFiles() + { + files = new JsonInternetSettingsFileSettings[cumulus.GraphDataFiles.Length] + }; + + var websettingsintervaleodgraph = new JsonInternetSettingsWebSettingsIntervalFiles() + { + files = new JsonInternetSettingsFileSettings[cumulus.GraphDataEodFiles.Length] + }; + + var websettingsinterval = new JsonInternetSettingsWebSettingsInterval() + { + enabled = cumulus.WebIntervalEnabled, + autoupdate = cumulus.WebAutoUpdate, + ftpinterval = cumulus.UpdateInterval, + stdfiles = websettingsintervalstd, + graphfiles = websettingsintervalgraph, + graphfileseod = websettingsintervaleodgraph + }; + + for (var i = 0; i < cumulus.StdWebFiles.Length; i++) + { + websettingsinterval.stdfiles.files[i] = new JsonInternetSettingsFileSettings() + { + filename = cumulus.StdWebFiles[i].LocalFileName, + create = cumulus.StdWebFiles[i].Create, + ftp = cumulus.StdWebFiles[i].FTP + }; + } + + for (var i =0; i < cumulus.GraphDataFiles.Length; i++) + { + websettingsinterval.graphfiles.files[i] = new JsonInternetSettingsFileSettings() + { + filename = cumulus.GraphDataFiles[i].LocalFileName, + create = cumulus.GraphDataFiles[i].Create, + ftp = cumulus.GraphDataFiles[i].FTP + }; + } + + for (var i = 0; i < cumulus.GraphDataEodFiles.Length; i++) + { + websettingsinterval.graphfileseod.files[i] = new JsonInternetSettingsFileSettings() + { + filename = cumulus.GraphDataEodFiles[i].LocalFileName, + create = cumulus.GraphDataEodFiles[i].Create, + ftp = cumulus.GraphDataEodFiles[i].FTP + }; + } + + var websettingsrealtime = new JsonInternetSettingsWebSettingsRealtime() + { + enabled = cumulus.RealtimeEnabled, + enablerealtimeftp = cumulus.RealtimeFTPEnabled, + realtimeinterval = cumulus.RealtimeInterval / 1000, + files = new JsonInternetSettingsFileSettings[cumulus.RealtimeFiles.Length] + }; + + for (var i = 0; i < cumulus.RealtimeFiles.Length; i++) + { + websettingsrealtime.files[i] = new JsonInternetSettingsFileSettings() + { + filename = cumulus.RealtimeFiles[i].LocalFileName, + create = cumulus.RealtimeFiles[i].Create, + ftp = cumulus.RealtimeFiles[i].FTP + }; + } + + var websettings = new JsonInternetSettingsWebSettings() + { + stdwebsite = false, + general = websettingsgeneral, + interval = websettingsinterval, + realtime = websettingsrealtime + }; + + + var externalprograms = new JsonInternetSettingsExternalPrograms() { dailyprogram = cumulus.DailyProgram, @@ -876,6 +999,13 @@ public class JsonInternetSettingsData public JsonInternetSettingsCustomHttpSettings customhttp { get; set; } } + public class JsonInternetSettingsWebsiteAdvanced + { + public bool activeftp { get; set; } + public bool disableftpsepsv { get; set; } + public bool disableftpsexplicit { get; set; } + } + public class JsonInternetSettingsWebsite { public string hostname { get; set; } @@ -888,26 +1018,58 @@ public class JsonInternetSettingsWebsite public string pskFile { get; set; } public string forumurl { get; set; } public string webcamurl { get; set; } + public JsonInternetSettingsWebsiteAdvanced advanced { get; set; } } public class JsonInternetSettingsWebSettings { - public bool autoupdate { get; set; } - public bool includestdfiles { get; set; } - public bool includegraphdatafiles { get; set; } - public bool activeftp { get; set; } + public bool stdwebsite { get; set; } + public JsonInternetSettingsWebSettingsGeneral general { get; set; } + public JsonInternetSettingsWebSettingsInterval interval { get; set; } + public JsonInternetSettingsWebSettingsRealtime realtime { get; set; } + + } + + public class JsonInternetSettingsWebSettingsGeneral + { public bool ftprename { get; set; } public bool ftpdelete { get; set; } public bool utf8encode { get; set; } public bool ftplogging { get; set; } + } + + public class JsonInternetSettingsFileSettings + { + public string filename { get; set; } + public bool create { get; set; } + public bool ftp { get; set; } + } + + public class JsonInternetSettingsWebSettingsInterval + { + public bool enabled { get; set; } + public bool autoupdate { get; set; } public int ftpinterval { get; set; } - public bool enablerealtime { get; set; } + public JsonInternetSettingsWebSettingsIntervalFiles stdfiles { get; set; } + public JsonInternetSettingsWebSettingsIntervalFiles graphfiles { get; set; } + public JsonInternetSettingsWebSettingsIntervalFiles graphfileseod { get; set; } + } + + public class JsonInternetSettingsWebSettingsIntervalFiles + { + public JsonInternetSettingsFileSettings[] files { get; set; } + + } + + public class JsonInternetSettingsWebSettingsRealtime + { + public bool enabled { get; set; } public bool enablerealtimeftp { get; set; } - public bool realtimetxtftp { get; set; } - public bool realtimegaugestxtftp { get; set; } public int realtimeinterval { get; set; } + public JsonInternetSettingsFileSettings[] files { get; set; } } + public class JsonInternetSettingsExternalPrograms { public string program { get; set; } diff --git a/CumulusMX/NOAA.cs b/CumulusMX/NOAA.cs index d833d0ad..6a667777 100644 --- a/CumulusMX/NOAA.cs +++ b/CumulusMX/NOAA.cs @@ -130,6 +130,8 @@ private double GetAverageWindSpeed(int month, int year, out int domdir) var logFile = cumulus.GetLogFileName(new DateTime(year, month, 2)); if (File.Exists(logFile)) { + var idx = 0; + var st = new List(); try { using (FileStream fs = new FileStream(logFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) @@ -143,13 +145,15 @@ private double GetAverageWindSpeed(int month, int year, out int domdir) var line = sr.ReadLine(); linenum++; - var st = new List(line.Split(cumulus.ListSeparator[0])); - double windspeed = Convert.ToSingle(st[5]); + st = new List(line.Split(cumulus.ListSeparator[0])); + idx = 5; + double windspeed = Convert.ToSingle(st[idx]); // add in wind speed sample for whole month windsamples++; totalwindspeed += windspeed; // add in direction if not done already - var winddir = Convert.ToInt32(st[7]); + idx = 7; + var winddir = Convert.ToInt32(st[idx]); totalwinddirX += (windspeed * Math.Sin((winddir * (Math.PI / 180)))); totalwinddirY += (windspeed * Math.Cos((winddir * (Math.PI / 180)))); //@ Unsupported property or method(C): 'EndOfStream' @@ -158,7 +162,7 @@ private double GetAverageWindSpeed(int month, int year, out int domdir) } catch (Exception e) { - cumulus.LogMessage("Error at line " + linenum + " of " + logFile + " : " + e.Message); + cumulus.LogMessage($"Error at line {linenum}, column {idx}, value '{(st.Count >= idx ? st[idx] : "")}' of {logFile} : {e}"); cumulus.LogMessage("Please edit the file to correct the error"); } } @@ -245,6 +249,8 @@ public List CreateMonthlyReport(DateTime thedate) int year = thedate.Year; int linenum = 0; string line; + int idx = 0; + List st = new List(); try { @@ -255,8 +261,9 @@ public List CreateMonthlyReport(DateTime thedate) { line = sr.ReadLine(); linenum++; - var st = new List(line.Split(cumulus.ListSeparator[0])); - string dateStr = st[0]; + st = new List(line.Split(cumulus.ListSeparator[0])); + idx = 0; + string dateStr = st[idx]; if ((Convert.ToInt32(dateStr.Substring(3, 2)) != month) || (Convert.ToInt32(dateStr.Substring(6, 2)) + 2000 != year)) continue; @@ -276,15 +283,17 @@ public List CreateMonthlyReport(DateTime thedate) // mean temp if ((st.Count > 15) && (st[15].Length > 0)) { - double meantemp = double.Parse(st[15]); + idx = 15; + double meantemp = double.Parse(st[idx]); totalmeantemp += meantemp; dayList[daynumber].meantemp = meantemp; // heating degree day - if ((st.Count > 40) && (st[40].Length > 0)) + idx = 40; + if ((st.Count > idx) && (st[idx].Length > 0)) { // read hdd from dayfile.txt - dayList[daynumber].heatingdegdays = double.Parse(st[40]); + dayList[daynumber].heatingdegdays = double.Parse(st[idx]); totalheating += double.Parse(st[40]); } else if (meantemp < cumulus.NOAAheatingthreshold) @@ -298,11 +307,12 @@ public List CreateMonthlyReport(DateTime thedate) } // cooling degree days - if ((st.Count > 41) && (st[41] != string.Empty)) + idx = 41; + if ((st.Count > idx) && (st[idx] != string.Empty)) { // read hdd from dayfile.txt - dayList[daynumber].coolingdegdays = double.Parse(st[41]); - totalcooling += double.Parse(st[41]); + dayList[daynumber].coolingdegdays = double.Parse(st[idx]); + totalcooling += double.Parse(st[idx]); } else if (meantemp > cumulus.NOAAcoolingthreshold) { @@ -323,8 +333,10 @@ public List CreateMonthlyReport(DateTime thedate) } // max temp - dayList[daynumber].maxtemp = double.Parse(st[6]); - string timestr = st[7]; + idx = 6; + dayList[daynumber].maxtemp = double.Parse(st[idx]); + idx = 7; + string timestr = st[idx]; int hour = Convert.ToInt32(timestr.Substring(0, 2)); int minute = Convert.ToInt32(timestr.Substring(3, 2)); dayList[daynumber].maxtemptimestamp = DateTime.MinValue.Date.Add(new TimeSpan(hour, minute, 0)); @@ -343,7 +355,8 @@ public List CreateMonthlyReport(DateTime thedate) } // min temp - dayList[daynumber].mintemp = double.Parse(st[4]); + idx = 4; + dayList[daynumber].mintemp = double.Parse(st[idx]); timestr = st[5]; hour = Convert.ToInt32(timestr.Substring(0, 2)); minute = Convert.ToInt32(timestr.Substring(3, 2)); @@ -363,8 +376,9 @@ public List CreateMonthlyReport(DateTime thedate) } // rain - dayList[daynumber].rain = double.Parse(st[14]); - totalrain += double.Parse(st[14]); + idx = 14; + dayList[daynumber].rain = double.Parse(st[idx]); + totalrain += double.Parse(st[idx]); if (dayList[daynumber].rain > maxrain) { maxrain = dayList[daynumber].rain; @@ -385,7 +399,8 @@ public List CreateMonthlyReport(DateTime thedate) } // high wind speed - dayList[daynumber].highwindspeed = double.Parse(st[1]); + idx = 1; + dayList[daynumber].highwindspeed = double.Parse(st[idx]); timestr = st[3]; hour = Convert.ToInt32(timestr.Substring(0, 2)); minute = Convert.ToInt32(timestr.Substring(3, 2)); @@ -397,9 +412,10 @@ public List CreateMonthlyReport(DateTime thedate) } // dominant wind bearing - if ((st.Count > 39) && (st[39] != string.Empty)) + idx = 39; + if ((st.Count > idx) && (st[idx] != string.Empty)) { - dayList[daynumber].winddomdir = Convert.ToInt32((st[39])); + dayList[daynumber].winddomdir = Convert.ToInt32((st[idx])); } daycount++; @@ -409,7 +425,7 @@ public List CreateMonthlyReport(DateTime thedate) } catch (Exception ex) { - cumulus.LogMessage("Error at line " + linenum + " of dayfile.txt: " + ex.Message); + cumulus.LogMessage($"Error at line {linenum}, column {idx}, value '{(st.Count >= idx ? st[idx] : "")}' of dayfile.txt: " + ex.Message); cumulus.LogMessage("Please edit the file to correct the error"); } @@ -418,6 +434,8 @@ public List CreateMonthlyReport(DateTime thedate) var logFile = cumulus.GetLogFileName(new DateTime(thedate.Year, thedate.Month, 2)); if (File.Exists(logFile)) + { + idx = 0; try { using (FileStream fs = new FileStream(logFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) @@ -430,13 +448,15 @@ public List CreateMonthlyReport(DateTime thedate) { line = sr.ReadLine(); linenum++; - var st = new List(line.Split(cumulus.ListSeparator[0])); + st = new List(line.Split(cumulus.ListSeparator[0])); - int entryday = Convert.ToInt32(st[0].Substring(0, 2)); - int entrymonth = Convert.ToInt32(st[0].Substring(3, 2)); - int entryyear = Convert.ToInt32(st[0].Substring(6, 2)); - int entryhour = Convert.ToInt32(st[1].Substring(0, 2)); - int entryminute = Convert.ToInt32(st[1].Substring(3, 2)); + idx = 0; + int entryday = Convert.ToInt32(st[idx].Substring(0, 2)); + int entrymonth = Convert.ToInt32(st[idx].Substring(3, 2)); + int entryyear = Convert.ToInt32(st[idx].Substring(6, 2)); + idx = 1; + int entryhour = Convert.ToInt32(st[idx].Substring(0, 2)); + int entryminute = Convert.ToInt32(st[idx].Substring(3, 2)); DateTime entrydate = new DateTime(entryyear, entrymonth, entryday, entryhour, entryminute, 0); @@ -447,7 +467,8 @@ public List CreateMonthlyReport(DateTime thedate) if (!dayList[daynumber].valid) continue; - double windspeed = double.Parse(st[5]); + idx = 5; + double windspeed = double.Parse(st[idx]); // add in wind speed sample for this day dayList[daynumber].windsamples++; @@ -460,18 +481,20 @@ public List CreateMonthlyReport(DateTime thedate) // add in direction if (not done already if (dayList[daynumber].winddomdir == 0) { - int winddir = Convert.ToInt32(st[7]); - dayList[daynumber].totalwinddirX += (windspeed*Math.Sin(Trig.DegToRad(winddir))); - dayList[daynumber].totalwinddirY += (windspeed*Math.Cos(Trig.DegToRad(winddir))); + idx = 7; + int winddir = Convert.ToInt32(st[idx]); + dayList[daynumber].totalwinddirX += (windspeed * Math.Sin(Trig.DegToRad(winddir))); + dayList[daynumber].totalwinddirY += (windspeed * Math.Cos(Trig.DegToRad(winddir))); } } while (!(sr.EndOfStream)); } } catch (Exception ex) { - cumulus.LogMessage("Error at line " + linenum + " of " + logFile + " : " + ex.Message); + cumulus.LogMessage($"Error at line {linenum}, column {idx}, value '{(st.Count >= idx ? st[idx] : "")}' of {logFile} : {ex}"); cumulus.LogMessage("Please edit the file to correct the error"); } + } double avgwindspeed; if (windsamples > 0) @@ -578,6 +601,8 @@ public List CreateMonthlyReport(DateTime thedate) var repLine = new StringBuilder(200); + var timeFormat = cumulus.NOAA12hourformat ? "h:mmtt" : "HH:mm"; + for (int i = 1; i <= DateTime.DaysInMonth(year, month); i++) { if (dayList[i].valid) @@ -594,25 +619,10 @@ public List CreateMonthlyReport(DateTime thedate) } ; repLine.Append(string.Format(culture, "{0,6:F1}", dayList[i].maxtemp)); - string timestr; - if (cumulus.NOAA12hourformat) - { - timestr = dayList[i].maxtemptimestamp.ToString("h:mmtt"); - } - else - { - timestr = dayList[i].maxtemptimestamp.ToString("HH:mm"); - } + string timestr = dayList[i].maxtemptimestamp.ToString(timeFormat); repLine.Append(string.Format("{0,8}", timestr)); repLine.Append(string.Format(culture, "{0,6:F1}", dayList[i].mintemp)); - if (cumulus.NOAA12hourformat) - { - timestr = dayList[i].mintemptimestamp.ToString("h:mmtt"); - } - else - { - timestr = dayList[i].mintemptimestamp.ToString("HH:mm"); - } + timestr = dayList[i].mintemptimestamp.ToString(timeFormat); repLine.Append(string.Format("{0,8}", timestr)); if (dayList[i].meantemp < -999) @@ -632,14 +642,7 @@ public List CreateMonthlyReport(DateTime thedate) repLine.Append(string.Format(culture, "{0,6:F1}", dayList[i].avgwindspeed)); repLine.Append(string.Format(culture, "{0,6:F1}", dayList[i].highwindspeed)); - if (cumulus.NOAA12hourformat) - { - timestr = dayList[i].highwindtimestamp.ToString("h:mmtt"); - } - else - { - timestr = dayList[i].highwindtimestamp.ToString("HH:mm"); - } + timestr = dayList[i].highwindtimestamp.ToString(timeFormat); repLine.Append(string.Format("{0,8}", timestr)); repLine.Append(string.Format("{0,6}", CompassPoint(dayList[i].winddomdir))); output.Add(repLine.ToString()); diff --git a/CumulusMX/NOAASettings.cs b/CumulusMX/NOAASettings.cs index 3ea5ed37..743c15ff 100644 --- a/CumulusMX/NOAASettings.cs +++ b/CumulusMX/NOAASettings.cs @@ -53,21 +53,36 @@ public string GetNoaaAlpacaFormData() oct = Math.Round(cumulus.NOAARainNorms[10], cumulus.RainDPlaces), nov = Math.Round(cumulus.NOAARainNorms[11], cumulus.RainDPlaces), dec = Math.Round(cumulus.NOAARainNorms[12], cumulus.RainDPlaces) - }; + }; - var data = new JsonNOAASettingsData() + var site = new JsonNOAASettingsSite() { sitename = cumulus.NOAAname, city = cumulus.NOAAcity, - state = cumulus.NOAAstate, - timeformat = cumulus.NOAA12hourformat?0:1, + state = cumulus.NOAAstate + }; + + var files = new JsonNOAASettingsOutput() + { monthfileformat = cumulus.NOAAMonthFileFormat, - yearfileformat = cumulus.NOAAYearFileFormat, + yearfileformat = cumulus.NOAAYearFileFormat + }; + + var options = new JsonNOAASettingsOptions() + { + timeformat = cumulus.NOAA12hourformat ? 1 : 0, utf8 = cumulus.NOAAUseUTF8, - dotdecimal = cumulus.NOAAUseDotDecimal, - autosave = cumulus.NOAAAutoSave, + dotdecimal = cumulus.NOAAUseDotDecimal + }; + + var ftp = new JsonNOAASettingsFtp() + { autoftp = cumulus.NOAAAutoFTP, - ftpdirectory = cumulus.NOAAFTPDirectory, + ftpdirectory = cumulus.NOAAFTPDirectory + }; + + var thresh = new JsonNOAASettingsThresholds() + { heatingthreshold = Math.Round(cumulus.NOAAheatingthreshold,cumulus.TempDPlaces), coolingthreshold = Math.Round(cumulus.NOAAcoolingthreshold,cumulus.TempDPlaces), maxtempcomp1 = Math.Round(cumulus.NOAAmaxtempcomp1,cumulus.RainDPlaces), @@ -76,7 +91,18 @@ public string GetNoaaAlpacaFormData() mintempcomp2 = Math.Round(cumulus.NOAAmintempcomp2,cumulus.RainDPlaces), raincomp1 = Math.Round(cumulus.NOAAraincomp1,cumulus.RainDPlaces), raincomp2 = Math.Round(cumulus.NOAAraincomp2,cumulus.RainDPlaces), - raincomp3 = Math.Round(cumulus.NOAAraincomp3, cumulus.RainDPlaces), + raincomp3 = Math.Round(cumulus.NOAAraincomp3, cumulus.RainDPlaces) + }; + + var data = new JsonNOAASettingsData() + { + autosave = cumulus.NOAAAutoSave, + + sitedetails = site, + outputfiles = files, + options = options, + ftp = ftp, + thresholds = thresh, normalmeantemps = normalmeantemps, normalrain = normalrain }; @@ -120,25 +146,29 @@ public string UpdateNoaaConfig(IHttpContext context) cumulus.NOAAAutoSave = settings.autosave; if (cumulus.NOAAAutoSave) { - cumulus.NOAAname = settings.sitename; - cumulus.NOAAcity = settings.city; - cumulus.NOAAstate = settings.state; - cumulus.NOAA12hourformat = settings.timeformat == 0; - cumulus.NOAAMonthFileFormat = settings.monthfileformat; - cumulus.NOAAYearFileFormat = settings.yearfileformat; - cumulus.NOAAUseUTF8 = settings.utf8; - cumulus.NOAAUseDotDecimal = settings.dotdecimal; - cumulus.NOAAAutoFTP = settings.autoftp; - cumulus.NOAAFTPDirectory = settings.ftpdirectory; - cumulus.NOAAheatingthreshold = settings.heatingthreshold; - cumulus.NOAAcoolingthreshold = settings.coolingthreshold; - cumulus.NOAAmaxtempcomp1 = settings.maxtempcomp1; - cumulus.NOAAmaxtempcomp2 = settings.maxtempcomp2; - cumulus.NOAAmintempcomp1 = settings.mintempcomp1; - cumulus.NOAAmintempcomp2 = settings.mintempcomp2; - cumulus.NOAAraincomp1 = settings.raincomp1; - cumulus.NOAAraincomp2 = settings.raincomp2; - cumulus.NOAAraincomp3 = settings.raincomp3; + cumulus.NOAAname = settings.sitedetails.sitename; + cumulus.NOAAcity = settings.sitedetails.city; + cumulus.NOAAstate = settings.sitedetails.state; + + cumulus.NOAAMonthFileFormat = settings.outputfiles.monthfileformat; + cumulus.NOAAYearFileFormat = settings.outputfiles.yearfileformat; + + cumulus.NOAA12hourformat = settings.options.timeformat == 1; + cumulus.NOAAUseUTF8 = settings.options.utf8; + cumulus.NOAAUseDotDecimal = settings.options.dotdecimal; + + cumulus.NOAAAutoFTP = settings.ftp.autoftp; + cumulus.NOAAFTPDirectory = settings.ftp.ftpdirectory; + + cumulus.NOAAheatingthreshold = settings.thresholds.heatingthreshold; + cumulus.NOAAcoolingthreshold = settings.thresholds.coolingthreshold; + cumulus.NOAAmaxtempcomp1 = settings.thresholds.maxtempcomp1; + cumulus.NOAAmaxtempcomp2 = settings.thresholds.maxtempcomp2; + cumulus.NOAAmintempcomp1 = settings.thresholds.mintempcomp1; + cumulus.NOAAmintempcomp2 = settings.thresholds.mintempcomp2; + cumulus.NOAAraincomp1 = settings.thresholds.raincomp1; + cumulus.NOAAraincomp2 = settings.thresholds.raincomp2; + cumulus.NOAAraincomp3 = settings.thresholds.raincomp3; // normal mean temps cumulus.NOAATempNorms[1] = settings.normalmeantemps.jan; @@ -185,29 +215,54 @@ public string UpdateNoaaConfig(IHttpContext context) } public class JsonNOAASettingsData + { + public bool autosave {get; set; } + public JsonNOAASettingsSite sitedetails { get; set; } + public JsonNOAASettingsOutput outputfiles { get; set; } + public JsonNOAASettingsOptions options { get; set; } + public JsonNOAASettingsFtp ftp { get; set; } + public JsonNOAASettingsThresholds thresholds { get; set; } + public JsonNOAASettingsNormalMeanTemps normalmeantemps {get; set; } + public JsonNOAASettingsNormalRain normalrain {get; set; } + } + + public class JsonNOAASettingsSite { public string sitename {get; set; } public string city {get; set; } public string state {get; set; } - public int timeformat {get; set; } + } + + public class JsonNOAASettingsOutput + { public string monthfileformat {get; set; } public string yearfileformat {get; set; } - public bool utf8 {get; set; } + } + + public class JsonNOAASettingsOptions + { + public int timeformat { get; set; } + public bool utf8 { get; set; } public bool dotdecimal { get; set; } - public bool autosave {get; set; } - public bool autoftp {get; set; } - public string ftpdirectory {get; set; } - public double heatingthreshold {get; set; } - public double coolingthreshold {get; set; } - public double maxtempcomp1 {get; set; } - public double maxtempcomp2 {get; set; } - public double mintempcomp1 {get; set; } - public double mintempcomp2 {get; set; } - public double raincomp1 {get; set; } - public double raincomp2 {get; set; } - public double raincomp3 {get; set; } - public JsonNOAASettingsNormalMeanTemps normalmeantemps {get; set; } - public JsonNOAASettingsNormalRain normalrain {get; set; } + } + + public class JsonNOAASettingsFtp + { + public bool autoftp { get; set; } + public string ftpdirectory { get; set; } + } + + public class JsonNOAASettingsThresholds + { + public double heatingthreshold { get; set; } + public double coolingthreshold { get; set; } + public double maxtempcomp1 { get; set; } + public double maxtempcomp2 { get; set; } + public double mintempcomp1 { get; set; } + public double mintempcomp2 { get; set; } + public double raincomp1 { get; set; } + public double raincomp2 { get; set; } + public double raincomp3 { get; set; } } public class JsonNOAASettingsNormalMeanTemps diff --git a/CumulusMX/Program.cs b/CumulusMX/Program.cs index 98897bea..9b0c38ff 100644 --- a/CumulusMX/Program.cs +++ b/CumulusMX/Program.cs @@ -37,8 +37,13 @@ private static void Main(string[] args) var logfile = "MXdiags" + Path.DirectorySeparatorChar + "ServiceConsoleLog.txt"; + var logfileOld = "MXdiags" + Path.DirectorySeparatorChar + "ServiceConsoleLog-Old.txt"; + if (File.Exists(logfileOld)) + File.Delete(logfileOld); + if (File.Exists(logfile)) - File.Delete(logfile); + File.Move(logfile, logfileOld); + svcTextListener = new TextWriterTraceListener(logfile); svcTextListener.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff ") + "Starting on " + (windows ? "Windows" : "Linux")); svcTextListener.Flush(); diff --git a/CumulusMX/StationSettings.cs b/CumulusMX/StationSettings.cs index bfafedd1..f30e644d 100644 --- a/CumulusMX/StationSettings.cs +++ b/CumulusMX/StationSettings.cs @@ -11,19 +11,25 @@ namespace CumulusMX internal class StationSettings { private readonly Cumulus cumulus; - private readonly WeatherStation station; + private WeatherStation station; private readonly string stationOptionsFile; private readonly string stationSchemaFile; - internal StationSettings(Cumulus cumulus, WeatherStation station) + //internal StationSettings(Cumulus cumulus, WeatherStation station) + internal StationSettings(Cumulus cumulus) { this.cumulus = cumulus; - this.station = station; + //this.station = station; stationOptionsFile = cumulus.AppDir + "interface"+Path.DirectorySeparatorChar+"json" + Path.DirectorySeparatorChar + "StationOptions.json"; stationSchemaFile = cumulus.AppDir + "interface"+Path.DirectorySeparatorChar+"json" + Path.DirectorySeparatorChar + "StationSchema.json"; } + internal void SetStation(WeatherStation station) + { + this.station = station; + } + internal string GetStationAlpacaFormData() { // Build the settings data, convert to JSON, and return it @@ -69,8 +75,8 @@ internal string GetStationAlpacaFormData() { wind = cumulus.Units.Wind, pressure = cumulus.Units.Press, - temp = cumulus.TempUnit, - rain = cumulus.RainUnit, + temp = cumulus.Units.Temp, + rain = cumulus.Units.Rain, advanced = unitsAdv }; @@ -221,7 +227,10 @@ internal string GetStationAlpacaFormData() graphWindChillVis = cumulus.GraphOptions.WCVisible, graphAppTempVis = cumulus.GraphOptions.AppTempVisible, graphFeelsLikeVis = cumulus.GraphOptions.FeelsLikeVisible, - graphHumidexVis = cumulus.GraphOptions.HumidexVisible + graphHumidexVis = cumulus.GraphOptions.HumidexVisible, + graphDailyAvgTempVis = cumulus.GraphOptions.DailyAvgTempVisible, + graphDailyMaxTempVis = cumulus.GraphOptions.DailyMaxTempVisible, + graphDailyMinTempVis = cumulus.GraphOptions.DailyMinTempVisible, }; var graphDataHum = new JsonStationSettingsGraphDataHumidity() @@ -465,6 +474,9 @@ internal string UpdateStationConfig(IHttpContext context) cumulus.GraphOptions.UVVisible = settings.Graphs.datavisibility.solar.graphUvVis; cumulus.GraphOptions.SolarVisible = settings.Graphs.datavisibility.solar.graphSolarVis; cumulus.GraphOptions.SunshineVisible = settings.Graphs.datavisibility.solar.graphSunshineVis; + cumulus.GraphOptions.DailyAvgTempVisible = settings.Graphs.datavisibility.temperature.graphDailyAvgTempVis; + cumulus.GraphOptions.DailyMaxTempVisible = settings.Graphs.datavisibility.temperature.graphDailyMaxTempVis; + cumulus.GraphOptions.DailyMinTempVisible = settings.Graphs.datavisibility.temperature.graphDailyMinTempVis; } catch (Exception ex) { @@ -830,8 +842,8 @@ internal string UpdateStationConfig(IHttpContext context) { cumulus.Units.Wind = settings.general.units.wind; cumulus.Units.Press = settings.general.units.pressure; - cumulus.TempUnit = settings.general.units.temp; - cumulus.RainUnit = settings.general.units.rain; + cumulus.Units.Temp = settings.general.units.temp; + cumulus.Units.Rain = settings.general.units.rain; cumulus.SetupUnitText(); cumulus.AirQualityDPlaces = settings.general.units.advanced.airqulaitydp; @@ -872,6 +884,13 @@ internal string UpdateStationConfig(IHttpContext context) // Save the settings cumulus.WriteIniFile(); + + // Graph configs may have changed, so re-create and upload the json files - just flag everything! + for (var i = 0; i < cumulus.GraphDataFiles.Length; i++) + { + cumulus.GraphDataFiles[i].CreateRequired = true; + cumulus.GraphDataFiles[i].FtpRequired = true; + } } catch (Exception ex) { @@ -885,6 +904,11 @@ internal string UpdateStationConfig(IHttpContext context) internal string FtpNow(IHttpContext context) { + if (station == null) + { + return "{\"result\":\"Not possible, station is not initialised\"}"; + } + try { var data = new StreamReader(context.Request.InputStream).ReadToEnd(); @@ -909,13 +933,18 @@ internal string FtpNow(IHttpContext context) if (cumulus.ftpThread.ThreadState == ThreadState.Running) cumulus.ftpThread.Abort(); - // If enabled (re)generate the daily graph data files, and upload - if (includeGraphs && cumulus.IncludeGraphDataFiles) + // Graph configs may have changed, so force re-create and upload the json files - just flag everything! + for (var i = 0; i < cumulus.GraphDataFiles.Length; i++) { - cumulus.LogDebugMessage("FTP Now: Generating the daily graph data files"); - station.CreateEodGraphDataFiles(); - cumulus.DailyGraphDataFilesNeedFTP = true; + cumulus.GraphDataFiles[i].CreateRequired = true; + cumulus.GraphDataFiles[i].FtpRequired = true; } + cumulus.LogDebugMessage("FTP Now: Re-Generating the graph data files, if required"); + station.CreateGraphDataFiles(); + + // (re)generate the daily graph data files, and upload if required + cumulus.LogDebugMessage("FTP Now: Generating the daily graph data files, if required"); + station.CreateEodGraphDataFiles(); cumulus.LogMessage("FTP Now: Trying new web update"); cumulus.WebUpdating = 1; @@ -924,13 +953,9 @@ internal string FtpNow(IHttpContext context) return "{\"result\":\"An existing FTP process was aborted, and a new FTP process invoked\"}"; } - // If enabled (re)generate the daily graph data files, and upload - if (includeGraphs && cumulus.IncludeGraphDataFiles) - { - cumulus.LogDebugMessage("FTP Now: Generating the daily graph data files"); - station.CreateEodGraphDataFiles(); - cumulus.DailyGraphDataFilesNeedFTP = true; - } + // (re)generate the daily graph data files, and upload if required + cumulus.LogDebugMessage("FTP Now: Generating the daily graph data files, if required"); + station.CreateEodGraphDataFiles(); cumulus.WebUpdating = 1; cumulus.ftpThread = new Thread(cumulus.DoHTMLFiles) { IsBackground = true }; @@ -1329,6 +1354,9 @@ public class JsonStationSettingsGraphDataTemperature public bool graphAppTempVis { get; set; } public bool graphFeelsLikeVis { get; set; } public bool graphHumidexVis { get; set; } + public bool graphDailyAvgTempVis { get; set; } + public bool graphDailyMaxTempVis { get; set; } + public bool graphDailyMinTempVis { get; set; } } public class JsonStationSettingsGraphDataHumidity diff --git a/CumulusMX/WMR100Station.cs b/CumulusMX/WMR100Station.cs index 130836df..228f9f0e 100644 --- a/CumulusMX/WMR100Station.cs +++ b/CumulusMX/WMR100Station.cs @@ -404,7 +404,7 @@ private void ProcessWindPacket() // wind chill negative wc = -wc; - if ((cumulus.TempUnit == 0)) + if ((cumulus.Units.Rain == 0)) // convert to C wc = (wc - 32)/1.8; diff --git a/CumulusMX/WMR200Station.cs b/CumulusMX/WMR200Station.cs index 8e9fd0f6..d4cbb816 100644 --- a/CumulusMX/WMR200Station.cs +++ b/CumulusMX/WMR200Station.cs @@ -737,7 +737,7 @@ private void ProcessRainPacket() private double ConvertWMR200Rain(double value) { double num; - if (cumulus.RainUnit == 0) + if (cumulus.Units.Rain == 0) { // mm num = value*25.4; @@ -875,7 +875,7 @@ private void ProcessWindPacket() if ((packetBuffer[13] & 0x80) == 0x80) wc = -wc; - if (cumulus.TempUnit == 0) + if (cumulus.Units.Rain == 0) { // convert to C wc = MeteoLib.FtoC(wc); @@ -1570,7 +1570,7 @@ private void ProcessHistoryDataPacket() // wind chill is in Fahrenheit! var wc = MeteoLib.FtoC((packetBuffer[25] + (packetBuffer[26] & 0xF)*256)/10.0); - if (cumulus.TempUnit == 0) + if (cumulus.Units.Rain == 0) { wc = MeteoLib.FtoC(wc); } diff --git a/CumulusMX/WeatherStation.cs b/CumulusMX/WeatherStation.cs index 0d87f87b..9da38e12 100644 --- a/CumulusMX/WeatherStation.cs +++ b/CumulusMX/WeatherStation.cs @@ -1719,7 +1719,7 @@ private void MinuteChanged(DateTime now) cumulus.CustomHttpMinutesUpdate(); } - if (cumulus.WebAutoUpdate && cumulus.SynchronisedWebUpdate && (now.Minute % cumulus.UpdateInterval == 0)) + if (cumulus.WebIntervalEnabled && cumulus.SynchronisedWebUpdate && (now.Minute % cumulus.UpdateInterval == 0)) { if (cumulus.WebUpdating == 1) { @@ -1837,7 +1837,8 @@ private void MinuteChanged(DateTime now) } } - if (cumulus.CreateWxnowTxt) + var wxfile = cumulus.StdWebFiles.SingleOrDefault(item => item.LocalFileName == "wxnow.txt"); + if (wxfile.Create) { CreateWxnowFile(); } @@ -2008,296 +2009,126 @@ private long DateTimeToJS(DateTime timestamp) public void CreateGraphDataFiles() { // Chart data for Highcharts graphs - // config - var json = GetGraphConfig(); - try - { - using (var file = new StreamWriter(cumulus.localGraphdataFiles[0], false)) - { - file.WriteLine(json); - file.Close(); - } - } - catch (Exception ex) - { - cumulus.LogMessage($"Error writing {cumulus.localGraphdataFiles[0]}: {ex.Message}"); - } - - // Temperature - json = GetTempGraphData(); - try - { - using (var file = new StreamWriter(cumulus.localGraphdataFiles[1], false)) - { - file.WriteLine(json); - file.Close(); - } - } - catch (Exception ex) - { - cumulus.LogMessage($"Error writing {cumulus.localGraphdataFiles[1]}: {ex.Message}"); - } - - // Pressure - json = GetPressGraphData(); - try - { - using (var file = new StreamWriter(cumulus.localGraphdataFiles[2], false)) - { - file.WriteLine(json); - file.Close(); - } - } - catch (Exception ex) - { - cumulus.LogMessage($"Error writing {cumulus.localGraphdataFiles[2]}: {ex.Message}"); - } - - // Wind - json = GetWindGraphData(); - try - { - using (var file = new StreamWriter(cumulus.localGraphdataFiles[3], false)) - { - file.WriteLine(json); - file.Close(); - } - } - catch (Exception ex) - { - cumulus.LogMessage($"Error writing {cumulus.localGraphdataFiles[3]}: {ex.Message}"); - } - - // Wind direction - json = GetWindDirGraphData(); - try - { - using (var file = new StreamWriter(cumulus.localGraphdataFiles[4], false)) - { - file.WriteLine(json); - file.Close(); - } - } - catch (Exception ex) - { - cumulus.LogMessage($"Error writing {cumulus.localGraphdataFiles[4]}: {ex.Message}"); - } - - // Humidity - json = GetHumGraphData(); - try - { - using (var file = new StreamWriter(cumulus.localGraphdataFiles[5], false)) - { - file.WriteLine(json); - file.Close(); - } - } - catch (Exception ex) - { - cumulus.LogMessage($"Error writing {cumulus.localGraphdataFiles[5]}: {ex.Message}"); - } - - // Rain - json = GetRainGraphData(); - try - { - using (var file = new StreamWriter(cumulus.localGraphdataFiles[6], false)) - { - file.WriteLine(json); - file.Close(); - } - } - catch (Exception ex) - { - cumulus.LogMessage($"Error writing {cumulus.localGraphdataFiles[6]}: {ex.Message}"); - } - - // Daily rain - json = GetDailyRainGraphData(); - try - { - using (var file = new StreamWriter(cumulus.localGraphdataFiles[7], false)) - { - file.WriteLine(json); - file.Close(); - } - } - catch (Exception ex) - { - cumulus.LogMessage($"Error writing {cumulus.localGraphdataFiles[7]}: {ex.Message}"); - } - - // Daily temp - json = GetDailyTempGraphData(); - try - { - using (var file = new StreamWriter(cumulus.localGraphdataFiles[8], false)) - { - file.WriteLine(json); - file.Close(); - } - } - catch (Exception ex) - { - cumulus.LogMessage($"Error writing {cumulus.localGraphdataFiles[8]}: {ex.Message}"); - } - - // Solar - json = GetSolarGraphData(); - try - { - using (var file = new StreamWriter(cumulus.localGraphdataFiles[9], false)) - { - file.WriteLine(json); - file.Close(); - } - } - catch (Exception ex) - { - cumulus.LogMessage($"Error writing {cumulus.localGraphdataFiles[9]}: {ex.Message}"); - } - - // Sun hours - json = GetSunHoursGraphData(); - try - { - using (var file = new StreamWriter(cumulus.localGraphdataFiles[10], false)) - { - file.WriteLine(json); - file.Close(); - } - } - catch (Exception ex) - { - cumulus.LogMessage($"Error writing {cumulus.localGraphdataFiles[10]}: {ex.Message}"); - } + string json = ""; + for (var i = 0; i < cumulus.GraphDataFiles.Length; i++) + { + // We double up the meaning of .FtpRequired to creation as well. + // The FtpRequired flag is only cleared for the config files that are pretty static so it is pointless + // recreating them every update too. + if (cumulus.GraphDataFiles[i].Create && cumulus.GraphDataFiles[i].CreateRequired) + { + switch (cumulus.GraphDataFiles[i].LocalFileName) + { + case "graphconfig.json": + json = GetGraphConfig(); + break; + case "availabledata.json": + json = GetAvailGraphData(); + break; + case "tempdata.json": + json = GetTempGraphData(); + break; + case "pressdata.json": + json = GetPressGraphData(); + break; + case "winddata.json": + json = GetWindGraphData(); + break; + case "wdirdata.json": + json = GetWindDirGraphData(); + break; + case "humdata.json": + json = GetHumGraphData(); + break; + case "raindata.json": + json = GetRainGraphData(); + break; + case "dailyrain.json": + json = GetDailyRainGraphData(); + break; + case "dailytemp.json": + json = GetDailyTempGraphData(); + break; + case "solardata.json": + json = GetSolarGraphData(); + break; + case "sunhours.json": + json = GetSunHoursGraphData(); + break; + case "airquality.json": + json = GetAqGraphData(); + break; + } - // Air Quality - json = GetAqGraphData(); - try - { - using (var file = new StreamWriter(cumulus.localGraphdataFiles[11], false)) - { - file.WriteLine(json); - file.Close(); - } - } - catch (Exception ex) - { - cumulus.LogMessage($"Error writing {cumulus.localGraphdataFiles[11]}: {ex.Message}"); - } + try + { + var dest = cumulus.GraphDataFiles[i].LocalPath + cumulus.GraphDataFiles[i].LocalFileName; + using (var file = new StreamWriter(dest, false)) + { + file.WriteLine(json); + file.Close(); + } - // Available graph data - json = GetAvailGraphData(); - try - { - using (var file = new StreamWriter(cumulus.localGraphdataFiles[12], false)) - { - file.WriteLine(json); - file.Close(); + // The config files only need creating once per change + if (cumulus.GraphDataFiles[i].LocalFileName == "availabledata.json" || cumulus.GraphDataFiles[i].LocalFileName == "graphconfig.json") + { + cumulus.GraphDataFiles[i].CreateRequired = false; + } + } + catch (Exception ex) + { + cumulus.LogMessage($"Error writing {cumulus.GraphDataFiles[i].LocalFileName}: {ex}"); + } } } - catch (Exception ex) - { - cumulus.LogMessage($"Error writing {cumulus.localGraphdataFiles[12]}: {ex.Message}"); - } - } public void CreateEodGraphDataFiles() { - string json; - - // Temperature - json = GetAllDailyTempGraphData(); - try - { - using (var file = new StreamWriter(cumulus.localDailyGraphdataFiles[0], false)) - { - file.WriteLine(json); - file.Close(); - } - } - catch (Exception ex) - { - cumulus.LogMessage($"Error writing {cumulus.localDailyGraphdataFiles[0]}: {ex.Message}"); - } - - // Pressure - json = GetAllDailyPressGraphData(); - try - { - using (var file = new StreamWriter(cumulus.localDailyGraphdataFiles[1], false)) - { - file.WriteLine(json); - file.Close(); - } - } - catch (Exception ex) - { - cumulus.LogMessage($"Error writing {cumulus.localDailyGraphdataFiles[1]}: {ex.Message}"); - } - - // Wind - json = GetAllDailyWindGraphData(); - try - { - using (var file = new StreamWriter(cumulus.localDailyGraphdataFiles[2], false)) - { - file.WriteLine(json); - file.Close(); - } - } - catch (Exception ex) - { - cumulus.LogMessage($"Error writing {cumulus.localDailyGraphdataFiles[2]}: {ex.Message}"); - } - - // Humidity - json = GetAllDailyHumGraphData(); - try - { - using (var file = new StreamWriter(cumulus.localDailyGraphdataFiles[3], false)) - { - file.WriteLine(json); - file.Close(); - } - } - catch (Exception ex) - { - cumulus.LogMessage($"Error writing {cumulus.localDailyGraphdataFiles[3]}: {ex.Message}"); - } - - // Rain - json = GetAllDailyRainGraphData(); - try - { - using (var file = new StreamWriter(cumulus.localDailyGraphdataFiles[4], false)) - { - file.WriteLine(json); - file.Close(); - } - } - catch (Exception ex) - { - cumulus.LogMessage($"Error writing {cumulus.localDailyGraphdataFiles[4]}: {ex.Message}"); - } + string json = ""; + for (var i = 0; i < cumulus.GraphDataEodFiles.Length; i++) + { + if (cumulus.GraphDataEodFiles[i].Create) + { + switch (cumulus.GraphDataEodFiles[i].LocalFileName) + { + case "alldailytempdata.json": + json = GetAllDailyTempGraphData(); + break; + case "alldailypressdata.json": + json = GetAllDailyPressGraphData(); + break; + case "alldailywinddata.json": + json = GetAllDailyWindGraphData(); + break; + case "alldailyhumdata.json": + json = GetAllDailyHumGraphData(); + break; + case "alldailyraindata.json": + json = GetAllDailyRainGraphData(); + break; + case "alldailysolardata.json": + json = GetAllDailySolarGraphData(); + break; + } - // Solar - json = GetAllDailySolarGraphData(); - try - { - using (var file = new StreamWriter(cumulus.localDailyGraphdataFiles[5], false)) - { - file.WriteLine(json); - file.Close(); + try + { + var dest = cumulus.GraphDataEodFiles[i].LocalPath + cumulus.GraphDataEodFiles[i].LocalFileName; + using (var file = new StreamWriter(dest, false)) + { + file.WriteLine(json); + file.Close(); + } + // Now set the flag that upload is required (if enabled) + cumulus.GraphDataEodFiles[i].FtpRequired = true; + } + catch (Exception ex) + { + cumulus.LogMessage($"Error writing {cumulus.GraphDataEodFiles[i].LocalFileName}: {ex}"); + } } } - catch (Exception ex) - { - cumulus.LogMessage($"Error writing {cumulus.localDailyGraphdataFiles[5]}: {ex.Message}"); - } } public string GetSolarGraphData() @@ -2717,7 +2548,7 @@ private void CreateWxnowFile() // h61 - humidity 61% (00 = 100%) // b10153 - barometric pressure in tenths of a millibar - 1015.3 millibars - var filename = cumulus.AppDir + cumulus.wxnowfile; + var filename = cumulus.AppDir + cumulus.WxnowFile; var timestamp = DateTime.Now.ToString(@"MMM dd yyyy HH\:mm"); int mphwind = Convert.ToInt32(ConvertUserWindToMPH(WindAverage)); @@ -2777,7 +2608,7 @@ private string APRStemp(double temp) // and return three digits int num; - if (cumulus.TempUnit == 0) + if (cumulus.Units.Rain == 0) { num = Convert.ToInt32(((temp * 1.8) + 32)); } @@ -2800,7 +2631,7 @@ private string APRStemp(double temp) private double ConvertUserRainToIn(double value) { - if (cumulus.RainUnit == 1) + if (cumulus.Units.Rain == 1) { return value; } @@ -3576,22 +3407,22 @@ public void DoRain(double total, double rate, DateTime timestamp) if (cumulus.Manufacturer == cumulus.DAVIS) // Davis can have either 0.2mm or 0.01in buckets, and the user could select to measure in mm or inches! { // If the bucket size is set, use that, otherwise infer from rain units - var bucketSize = cumulus.DavisOptions.RainGaugeType == -1 ? cumulus.RainUnit : cumulus.DavisOptions.RainGaugeType; + var bucketSize = cumulus.DavisOptions.RainGaugeType == -1 ? cumulus.Units.Rain : cumulus.DavisOptions.RainGaugeType; if (bucketSize == 0) // 0.2 mm tips { // mm/mm (0.2) or mm/in (0.00787) - raintipthreshold = cumulus.RainUnit == 0 ? 0.19 : 0.006; + raintipthreshold = cumulus.Units.Rain == 0 ? 0.19 : 0.006; } else // 0.01 inch tips { // in/mm (0.254) or in/in (0.01) - raintipthreshold = cumulus.RainUnit == 0 ? 0.2 : 0.009; + raintipthreshold = cumulus.Units.Rain == 0 ? 0.2 : 0.009; } } else { - if (cumulus.RainUnit == 0) + if (cumulus.Units.Rain == 0) { // mm raintipthreshold = cumulus.Manufacturer == cumulus.INSTROMET ? 0.009 : 0.09; @@ -4644,7 +4475,7 @@ public void DayReset(DateTime timestamp) if (cumulus.RainDayThreshold < 0) // default { - if (cumulus.RainUnit == 0) + if (cumulus.Units.Rain == 0) { rdthresh1000 = 200; // 0.2mm *1000 } @@ -5270,11 +5101,8 @@ public void DayReset(DateTime timestamp) // Do the Daily graph data files CreateEodGraphDataFiles(); - if (cumulus.IncludeGraphDataFiles) - { - cumulus.DailyGraphDataFilesNeedFTP = true; - cumulus.LogMessage("Daily graph data files will be uploaded at next web update"); - } + cumulus.LogMessage("If required the daily graph data files will be uploaded at next web update"); + if (!string.IsNullOrEmpty(cumulus.DailyProgram)) { @@ -5695,7 +5523,7 @@ protected int BCDchartoint(int c) /// Temp in configured units public double ConvertTempCToUser(double value) { - if (cumulus.TempUnit == 1) + if (cumulus.Units.Rain == 1) { return MeteoLib.CToF(value); } @@ -5713,7 +5541,7 @@ public double ConvertTempCToUser(double value) /// Temp in configured units public double ConvertTempFToUser(double value) { - if (cumulus.TempUnit == 0) + if (cumulus.Units.Rain == 0) { return MeteoLib.FtoC(value); } @@ -5731,7 +5559,7 @@ public double ConvertTempFToUser(double value) /// Temp in C public double ConvertUserTempToC(double value) { - if (cumulus.TempUnit == 1) + if (cumulus.Units.Rain == 1) { return MeteoLib.FtoC(value); } @@ -5749,7 +5577,7 @@ public double ConvertUserTempToC(double value) /// Temp in F public double ConvertUserTempToF(double value) { - if (cumulus.TempUnit == 1) + if (cumulus.Units.Rain == 1) { return value; } @@ -5891,7 +5719,7 @@ public double ConvertUserWindToKPH(double wind) // input is in Units.Wind units, /// Rain in configured units public virtual double ConvertRainMMToUser(double value) { - return cumulus.RainUnit == 1 ? value * 0.0393700787 : value; + return cumulus.Units.Rain == 1 ? value * 0.0393700787 : value; } /// @@ -5901,7 +5729,7 @@ public virtual double ConvertRainMMToUser(double value) /// Rain in configured units public virtual double ConvertRainINToUser(double value) { - return cumulus.RainUnit == 1 ? value : value * 25.4; + return cumulus.Units.Rain == 1 ? value : value * 25.4; } /// @@ -5911,7 +5739,7 @@ public virtual double ConvertRainINToUser(double value) /// Rain in mm public virtual double ConvertUserRainToMM(double value) { - return cumulus.RainUnit == 1 ? value / 0.0393700787 : value; + return cumulus.Units.Rain == 1 ? value / 0.0393700787 : value; } /// @@ -8269,6 +8097,7 @@ public void ReadMonthIniFile() public void WriteMonthIniFile() { + cumulus.LogDebugMessage("Writing to Month.ini file"); lock (monthIniThreadLock) { try @@ -8351,6 +8180,7 @@ public void WriteMonthIniFile() cumulus.LogMessage("Error writing month.ini file: " + ex.Message); } } + cumulus.LogDebugMessage("End writing to Month.ini file"); } public void ReadYearIniFile() @@ -9206,7 +9036,7 @@ public string GetWOWURL(out string pwstring, DateTime timestamp) public double ConvertUserRainToIN(double rain) { - if (cumulus.RainUnit == 0) + if (cumulus.Units.Rain == 0) { return rain * 0.0393700787; } @@ -10512,6 +10342,24 @@ public string GetAvailGraphData() // rain json.Append("\"Rain\":[\"Rainfall\",\"Rainfall Rate\"]"); + if (cumulus.GraphOptions.DailyAvgTempVisible || cumulus.GraphOptions.DailyMaxTempVisible || cumulus.GraphOptions.DailyMinTempVisible) + { + json.Append(",\"DailyTemps\":["); + + if (cumulus.GraphOptions.DailyAvgTempVisible) + json.Append("\"AvgTemp\","); + if (cumulus.GraphOptions.DailyMaxTempVisible) + json.Append("\"MaxTemp\","); + if (cumulus.GraphOptions.DailyMinTempVisible) + json.Append("\"MinTemp\","); + + if (json.ToString().EndsWith(",")) + json.Length--; + + json.Append("]"); + } + + // solar values if (cumulus.GraphOptions.SolarVisible || cumulus.GraphOptions.UVVisible) { @@ -10529,13 +10377,18 @@ public string GetAvailGraphData() json.Append("]"); } + // Sunshine + if (cumulus.GraphOptions.SunshineVisible) + { + json.Append(",\"Sunshine\":[\"sunhours\"]"); + } // air quality // Check if we are to generate AQ data at all. Only if a primary sensor is defined and it isn't the Indoor AirLink if (cumulus.StationOptions.PrimaryAqSensor > (int)Cumulus.PrimaryAqSensor.Undefined && cumulus.StationOptions.PrimaryAqSensor != (int)Cumulus.PrimaryAqSensor.AirLinkIndoor) { - json.Append(",\"Air Quality\":["); + json.Append(",\"AirQuality\":["); json.Append("\"PM 2.5\""); // Only the AirLink and Ecowitt CO2 servers provide PM10 values at the moment @@ -10582,7 +10435,7 @@ public string GetSunHoursGraphData() { var InvC = new CultureInfo(""); StringBuilder sb = new StringBuilder("{", 10000); - if (cumulus.GraphOptions.SolarVisible) + if (cumulus.GraphOptions.SunshineVisible) { var datefrom = DateTime.Now.AddDays(-cumulus.GraphDays - 1); var data = DayFile.Where(rec => rec.Date >= datefrom).ToList(); @@ -10607,33 +10460,59 @@ public string GetDailyTempGraphData() var InvC = new CultureInfo(""); var datefrom = DateTime.Now.AddDays(-cumulus.GraphDays - 1); var data = DayFile.Where(rec => rec.Date >= datefrom).ToList(); + var append = false; + StringBuilder sb = new StringBuilder("{"); - StringBuilder sb = new StringBuilder("{\"mintemp\":["); - - for (var i = 0; i < data.Count; i++) + if (cumulus.GraphOptions.DailyMinTempVisible) { - sb.Append($"[{DateTimeToUnix(data[i].Date) * 1000},{data[i].LowTemp.ToString(cumulus.TempFormat, InvC)}]"); - if (i < data.Count - 1) - sb.Append(","); + sb.Append("\"mintemp\":["); + + for (var i = 0; i < data.Count; i++) + { + sb.Append($"[{DateTimeToUnix(data[i].Date) * 1000},{data[i].LowTemp.ToString(cumulus.TempFormat, InvC)}]"); + if (i < data.Count - 1) + sb.Append(","); + } + + sb.Append("]"); + append = true; } - sb.Append("],\"maxtemp\":["); - for (var i = 0; i < data.Count; i++) + if (cumulus.GraphOptions.DailyMaxTempVisible) { - sb.Append($"[{DateTimeToUnix(data[i].Date) * 1000},{data[i].HighTemp.ToString(cumulus.TempFormat, InvC)}]"); - if (i < data.Count - 1) + if (append) sb.Append(","); + + sb.Append("\"maxtemp\":["); + + for (var i = 0; i < data.Count; i++) + { + sb.Append($"[{DateTimeToUnix(data[i].Date) * 1000},{data[i].HighTemp.ToString(cumulus.TempFormat, InvC)}]"); + if (i < data.Count - 1) + sb.Append(","); + } + + sb.Append("]"); + append = true; } - sb.Append("],\"avgtemp\":["); - for (var i = 0; i < data.Count; i++) + if (cumulus.GraphOptions.DailyAvgTempVisible) { - sb.Append($"[{DateTimeToUnix(data[i].Date) * 1000},{data[i].AvgTemp.ToString(cumulus.TempFormat, InvC)}]"); - if (i < data.Count - 1) + if (append) sb.Append(","); + + sb.Append("\"avgtemp\":["); + for (var i = 0; i < data.Count; i++) + { + sb.Append($"[{DateTimeToUnix(data[i].Date) * 1000},{data[i].AvgTemp.ToString(cumulus.TempFormat, InvC)}]"); + if (i < data.Count - 1) + sb.Append(","); + } + + sb.Append("]"); } - sb.Append("]}"); + sb.Append("}"); return sb.ToString(); } @@ -10671,11 +10550,14 @@ public string GetAllDailyTempGraphData() { var recDate = DateTimeToUnix(DayFile[i].Date) * 1000; // lo temp - minTemp.Append($"[{recDate},{DayFile[i].LowTemp.ToString(cumulus.TempFormat, InvC)}]"); + if (cumulus.GraphOptions.DailyMinTempVisible) + minTemp.Append($"[{recDate},{DayFile[i].LowTemp.ToString(cumulus.TempFormat, InvC)}]"); // hi temp - maxTemp.Append($"[{recDate},{DayFile[i].HighTemp.ToString(cumulus.TempFormat, InvC)}]"); + if (cumulus.GraphOptions.DailyMaxTempVisible) + maxTemp.Append($"[{recDate},{DayFile[i].HighTemp.ToString(cumulus.TempFormat, InvC)}]"); // avg temp - avgTemp.Append($"[{recDate},{DayFile[i].AvgTemp.ToString(cumulus.TempFormat, InvC)}]"); + if (cumulus.GraphOptions.DailyAvgTempVisible) + avgTemp.Append($"[{recDate},{DayFile[i].AvgTemp.ToString(cumulus.TempFormat, InvC)}]"); if (i < len) { @@ -10782,31 +10664,35 @@ public string GetAllDailyTempGraphData() } } } - sb.Append("\"minTemp\":" + minTemp.ToString() + "],"); - sb.Append("\"maxTemp\":" + maxTemp.ToString() + "],"); - sb.Append("\"avgTemp\":" + avgTemp.ToString() + "]"); + if (cumulus.GraphOptions.DailyMinTempVisible) + sb.Append("\"minTemp\":" + minTemp.ToString() + "],"); + if (cumulus.GraphOptions.DailyMaxTempVisible) + sb.Append("\"maxTemp\":" + maxTemp.ToString() + "],"); + if (cumulus.GraphOptions.DailyAvgTempVisible) + sb.Append("\"avgTemp\":" + avgTemp.ToString() + "],"); if (cumulus.GraphOptions.HIVisible) - sb.Append(",\"heatIndex\":" + heatIdx.ToString() + "]"); + sb.Append("\"heatIndex\":" + heatIdx.ToString() + "],"); if (cumulus.GraphOptions.AppTempVisible) { - sb.Append(",\"maxApp\":" + maxApp.ToString() + "]"); - sb.Append(",\"minApp\":" + minApp.ToString() + "]"); + sb.Append("\"maxApp\":" + maxApp.ToString() + "],"); + sb.Append("\"minApp\":" + minApp.ToString() + "],"); } if (cumulus.GraphOptions.WCVisible) - sb.Append(",\"windChill\":" + windChill.ToString() + "]"); + sb.Append("\"windChill\":" + windChill.ToString() + "],"); if (cumulus.GraphOptions.DPVisible) { - sb.Append(",\"maxDew\":" + maxDew.ToString() + "]"); - sb.Append(",\"minDew\":" + minDew.ToString() + "]"); + sb.Append("\"maxDew\":" + maxDew.ToString() + "],"); + sb.Append("\"minDew\":" + minDew.ToString() + "],"); } if (cumulus.GraphOptions.FeelsLikeVisible) { - sb.Append(",\"maxFeels\":" + maxFeels.ToString() + "]"); - sb.Append(",\"minFeels\":" + minFeels.ToString() + "]"); + sb.Append("\"maxFeels\":" + maxFeels.ToString() + "],"); + sb.Append("\"minFeels\":" + minFeels.ToString() + "],"); } if (cumulus.GraphOptions.HumidexVisible) - sb.Append(",\"humidex\":" + humidex.ToString() + "]"); + sb.Append("\"humidex\":" + humidex.ToString() + "],"); + sb.Length--; sb.Append("}"); return sb.ToString(); diff --git a/CumulusMX/webtags.cs b/CumulusMX/webtags.cs index a4bbaf79..ff2f32e6 100644 --- a/CumulusMX/webtags.cs +++ b/CumulusMX/webtags.cs @@ -2867,7 +2867,7 @@ private string Tagforum(Dictionary tagParams) return string.Empty; } - return @":forum:"; + return $":forum:"; } private string Tagwebcam(Dictionary tagParams) diff --git a/Updates.txt b/Updates.txt index c14c4ba1..f7d145bd 100644 --- a/Updates.txt +++ b/Updates.txt @@ -1,20 +1,24 @@ -3.10.0 - b3109 +3.10.0 - b310x —————————————— -- Change: All the settings screens revamped and reorganised. - - Many of the settings are now context senstive, only showing items relevant to your station and configuration - - Most of the previously config file "read-only" settings are now available in an Advanced section relevant to the configuration item. These settings are now read/write. - - - -3.9.8 - b3108 -————————————— - Fix: Catch error creating System Uptime counter on Windows +- Fix: The Local web server is now brought up before initialising the station. This allows you to correct a misconfigured station without resorting to editing the Cumulus.ini file. + +- New: The previous Console log file is now copied to an "-old" file on start-up +- Change: All the settings screens revamped, reorganised and extended. + - Many of the settings are now context sensitive, only showing items relevant to your station and configuration. + - Most of the previously config file "read-only" settings are now available in an Advanced section relevant to the configuration item. These settings are now read/write. + - Many new Cumulus.ini configuration entries, and some now depreciated. + - Virtually all the standard files that can be generated can now be controlled for enabling/disabling generation and FTP transfer independently. + - Added more graph data series controls. +- Change: The two graph config files availabledata.json and graphconfig.json are now only uploaded on program start-up and when the station config is changed. +- Change: Dayfile, Monthly Log, and Extra log file editors now have a selectable page length, and a goto-page feature +- Change: The default web site is now driven by a single data file (plus realtimegauges.txt), rather than every page being updated and uploaded each interval. +- Change: The various charting pages now hide buttons for graphs that do not contain any data - both on the dashboard and default web site. - Change: Creation of the wxnow.txt file is now disabled by default for new installs - Change: Clock sync (Davis VP2 & Instromet) now occurs at 2 minutes past the hour selected - 3.9.7 - b3107 ————————————— - Fix: Unhandled exception in ProcessTemplateFile if cumulus cannot write to the output file From 3069131b0d09025ddd678cf85ef2bc680986f909 Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Sun, 14 Feb 2021 23:55:36 +0000 Subject: [PATCH 05/12] b3110 --- CumulusMX/Cumulus.cs | 6 +- CumulusMX/DataEditor.cs | 31 ++++- CumulusMX/DavisWllStation.cs | 6 +- CumulusMX/InternetSettings.cs | 1 - CumulusMX/Properties/AssemblyInfo.cs | 6 +- CumulusMX/StationSettings.cs | 179 +++++++++++++-------------- Updates.txt | 5 +- 7 files changed, 128 insertions(+), 106 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index aac5ef95..c5adabc1 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -3396,7 +3396,7 @@ private void ReadIniFile() // Davis Options DavisOptions.UseLoop2 = ini.GetValue("Station", "UseDavisLoop2", true); - DavisOptions.ReadReceptionStats = ini.GetValue("Station", "DavisReadReceptionStats", false); + DavisOptions.ReadReceptionStats = ini.GetValue("Station", "DavisReadReceptionStats", true); DavisOptions.SetLoggerInterval = ini.GetValue("Station", "DavisSetLoggerInterval", false); DavisOptions.InitWaitTime = ini.GetValue("Station", "DavisInitWaitTime", 2000); DavisOptions.IPResponseTime = ini.GetValue("Station", "DavisIPResponseTime", 500); @@ -4252,7 +4252,7 @@ private void ReadIniFile() } NOAAYearFileFormat = ini.GetValue("NOAA", "YearFileFormat", "'NOAAYR'yyyy'.txt'"); NOAAFTPDirectory = ini.GetValue("NOAA", "FTPDirectory", ""); - NOAAUseUTF8 = ini.GetValue("NOAA", "NOAAUseUTF8", false); + NOAAUseUTF8 = ini.GetValue("NOAA", "NOAAUseUTF8", true); NOAAUseDotDecimal = ini.GetValue("NOAA", "UseDotDecimal", false); NOAATempNorms[1] = ini.GetValue("NOAA", "NOAATempNormJan", -1000.0); @@ -5497,7 +5497,7 @@ private void ReadStringsFile() public string HTTPProxyName { get; set; } - public int[] WindDPlaceDefaults = { 1, 1, 1, 1 }; + public int[] WindDPlaceDefaults = { 1, 0, 0, 0 }; // m/s, mph, km/h, knots public int[] TempDPlaceDefaults = { 1, 1 }; public int[] PressDPlaceDefaults = { 1, 1, 2 }; public int[] RainDPlaceDefaults = { 1, 2 }; diff --git a/CumulusMX/DataEditor.cs b/CumulusMX/DataEditor.cs index d9af8492..f4931cd8 100644 --- a/CumulusMX/DataEditor.cs +++ b/CumulusMX/DataEditor.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using System.Text; -using System.Text.RegularExpressions; using Unosquare.Labs.EmbedIO; using ServiceStack; @@ -18,11 +17,37 @@ internal class DataEditor private readonly List hourRainLog = new List(); - //internal DataEditor(Cumulus cumulus, WeatherStation station, WebTags webtags) internal DataEditor(Cumulus cumulus) { - //this.station = station; this.cumulus = cumulus; + + // Formats to use for the different date kinds + string utcTimeFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"; + string localTimeFormat = "yyyy-MM-dd'T'HH:mm:ss"; + + // Override the ServiceStack Deserialization function + // Check which format provided, attempt to parse as datetime or return minValue. + ServiceStack.Text.JsConfig.DeSerializeFn = datetimeStr => + { + if (string.IsNullOrWhiteSpace(datetimeStr)) + { + return DateTime.MinValue; + } + + if (datetimeStr.EndsWith("Z") && + DateTime.TryParseExact(datetimeStr, utcTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out DateTime resultUtc)) + { + return resultUtc; + } + else if (!datetimeStr.EndsWith("Z") && + DateTime.TryParseExact(datetimeStr, localTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out DateTime resultLocal)) + { + return resultLocal; + } + + return DateTime.MinValue; + }; + } internal void SetStation(WeatherStation station) diff --git a/CumulusMX/DavisWllStation.cs b/CumulusMX/DavisWllStation.cs index 37d92350..fb052aa4 100644 --- a/CumulusMX/DavisWllStation.cs +++ b/CumulusMX/DavisWllStation.cs @@ -2584,12 +2584,14 @@ private void GetWlHistoricHealth() // AirLink Outdoor case 506 when lsid == alOutHealthLsid: // Pass AirLink historic record to the AirLink module to process - cumulus.airLinkOut.DecodeWlApiHealth(sensor, true); + if (cumulus.airLinkOut != null) + cumulus.airLinkOut.DecodeWlApiHealth(sensor, true); break; // AirLink Indoor case 506 when lsid == alInHealthLsid: // Pass AirLink historic record to the AirLink module to process - cumulus.airLinkIn.DecodeWlApiHealth(sensor, true); + if (cumulus.airLinkIn != null) + cumulus.airLinkIn.DecodeWlApiHealth(sensor, true); break; default: if (sensorType == 504 || dataStructureType == 11) diff --git a/CumulusMX/InternetSettings.cs b/CumulusMX/InternetSettings.cs index 4c9b1bec..e1754726 100644 --- a/CumulusMX/InternetSettings.cs +++ b/CumulusMX/InternetSettings.cs @@ -22,7 +22,6 @@ public InternetSettings(Cumulus cumulus) internetSchemaFile = cumulus.AppDir + "interface" + Path.DirectorySeparatorChar + "json" + Path.DirectorySeparatorChar + "InternetSchema.json"; } - //public string UpdateInternetConfig(HttpListenerContext context) public string UpdateInternetConfig(IHttpContext context) { var errorMsg = ""; diff --git a/CumulusMX/Properties/AssemblyInfo.cs b/CumulusMX/Properties/AssemblyInfo.cs index f97d0353..d80049c6 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("Build 3109")] +[assembly: AssemblyDescription("Build 3110")] [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.10.0.3109")] -[assembly: AssemblyFileVersion("3.10.0.3109")] +[assembly: AssemblyVersion("3.10.0.3110")] +[assembly: AssemblyFileVersion("3.10.0.3110")] diff --git a/CumulusMX/StationSettings.cs b/CumulusMX/StationSettings.cs index f30e644d..51f27ffc 100644 --- a/CumulusMX/StationSettings.cs +++ b/CumulusMX/StationSettings.cs @@ -15,11 +15,9 @@ internal class StationSettings private readonly string stationOptionsFile; private readonly string stationSchemaFile; - //internal StationSettings(Cumulus cumulus, WeatherStation station) internal StationSettings(Cumulus cumulus) { this.cumulus = cumulus; - //this.station = station; stationOptionsFile = cumulus.AppDir + "interface"+Path.DirectorySeparatorChar+"json" + Path.DirectorySeparatorChar + "StationOptions.json"; stationSchemaFile = cumulus.AppDir + "interface"+Path.DirectorySeparatorChar+"json" + Path.DirectorySeparatorChar + "StationSchema.json"; @@ -48,8 +46,6 @@ internal string GetStationAlpacaFormData() use100for98hum = cumulus.StationOptions.Humidity98Fix, calculatedewpoint = cumulus.StationOptions.CalculatedDP, calculatewindchill = cumulus.StationOptions.CalculatedWC, - syncstationclock = cumulus.StationOptions.SyncTime, - syncclockhour = cumulus.StationOptions.ClockSettingHour, cumuluspresstrendnames = cumulus.StationOptions.UseCumulusPresstrendstr, extrasensors = cumulus.StationOptions.LogExtraSensors, ignorelacrosseclock = cumulus.StationOptions.WS2300IgnoreStationClock, @@ -83,46 +79,41 @@ internal string GetStationAlpacaFormData() var tcpsettings = new JsonStationSettingsTCPsettings() { ipaddress = cumulus.DavisOptions.IPAddr, - tcpport = cumulus.DavisOptions.TCPPort, disconperiod = cumulus.DavisOptions.PeriodicDisconnectInterval }; - var davisconn = new JsonStationSettingsDavisConn() - { - conntype = cumulus.DavisOptions.ConnectionType, - tcpsettings = tcpsettings - }; - - var davisCommonAdvanced = new JsonStationSettingsDavisCommonAdvanced() - { - raingaugetype = cumulus.DavisOptions.RainGaugeType - }; - - var davisCommon = new JsonStationSettingsDavisCommon() - { - davisconn = davisconn, - advanced = davisCommonAdvanced - }; var davisvp2advanced = new JsonStationSettingsDavisVp2Advanced() { + syncstationclock = cumulus.StationOptions.SyncTime, + syncclockhour = cumulus.StationOptions.ClockSettingHour, useloop2 = cumulus.DavisOptions.UseLoop2, + raingaugetype = cumulus.DavisOptions.RainGaugeType, vp1minbarupdate = cumulus.DavisOptions.ForceVPBarUpdate, initwaittime = cumulus.DavisOptions.InitWaitTime, ipresponsetime = cumulus.DavisOptions.IPResponseTime, - baudrate = cumulus.DavisOptions.BaudRate + baudrate = cumulus.DavisOptions.BaudRate, + readreceptionstats = cumulus.DavisOptions.ReadReceptionStats, + tcpport = cumulus.DavisOptions.TCPPort, + setloggerinterval = cumulus.DavisOptions.SetLoggerInterval + }; + + var davisvp2conn = new JsonStationSettingsDavisVp2Connection() + { + conntype = cumulus.DavisOptions.ConnectionType, + comportname = cumulus.ComportName, + tcpsettings = tcpsettings }; var davisvp2 = new JsonStationSettingsDavisVp2() { - readreceptionstats = cumulus.DavisOptions.ReadReceptionStats, - setloggerinterval = cumulus.DavisOptions.SetLoggerInterval, + davisconn = davisvp2conn, advanced = davisvp2advanced }; - var gw1000 = new JSonStationSettingsGw1000Conn() {ipaddress = cumulus.Gw1000IpAddress, autoDiscover = cumulus.Gw1000AutoUpdateIpAddress, macaddress = cumulus.Gw1000MacAddress }; + var gw1000 = new JSonStationSettingsGw1000Conn() { ipaddress = cumulus.Gw1000IpAddress, autoDiscover = cumulus.Gw1000AutoUpdateIpAddress, macaddress = cumulus.Gw1000MacAddress }; - var logrollover = new JsonStationSettingsLogRollover() {time = "midnight",summer10am = cumulus.Use10amInSummer}; + var logrollover = new JsonStationSettingsLogRollover() { time = "midnight",summer10am = cumulus.Use10amInSummer }; if (cumulus.RolloverHour == 9) { @@ -155,6 +146,8 @@ internal string GetStationAlpacaFormData() var imetAdvanced = new JsonStationSettingsImetAdvanced() { + syncstationclock = cumulus.StationOptions.SyncTime, + syncclockhour = cumulus.StationOptions.ClockSettingHour, readdelay = cumulus.ImetOptions.ImetReadDelay, waittime = cumulus.ImetOptions.ImetWaitTime, updatelogpointer = cumulus.ImetOptions.ImetUpdateLogPointer @@ -162,6 +155,7 @@ internal string GetStationAlpacaFormData() var imet = new JsonStationSettingsImet() { + comportname = cumulus.ComportName, baudrate = cumulus.ImetOptions.ImetBaudRate, advanced = imetAdvanced }; @@ -262,7 +256,14 @@ internal string GetStationAlpacaFormData() var wllNetwork = new JsonStationSettingsWLLNetwork() { - autoDiscover = cumulus.WLLAutoUpdateIpAddress + autoDiscover = cumulus.WLLAutoUpdateIpAddress, + ipaddress = cumulus.DavisOptions.IPAddr + }; + + var wllAdvanced = new JsonStationSettingsWLLAdvanced() + { + raingaugetype = cumulus.DavisOptions.RainGaugeType, + tcpport = cumulus.DavisOptions.TCPPort }; var wllApi = new JsonStationSettingsWLLApi() @@ -337,13 +338,13 @@ internal string GetStationAlpacaFormData() api = wllApi, primary = wllPrimary, soilLeaf = wllSoilLeaf, - extraTemp = wllExtraTemp + extraTemp = wllExtraTemp, + advanced = wllAdvanced }; var general = new JsonStationGeneral() { stationtype = cumulus.StationType, - comportname = cumulus.ComportName, loginterval = cumulus.DataLogInterval, logrollover = logrollover, units = units, @@ -354,7 +355,6 @@ internal string GetStationAlpacaFormData() { stationid = cumulus.StationType, general = general, - daviscommon = davisCommon, davisvp2 = davisvp2, daviswll = wll, gw1000 = gw1000, @@ -586,8 +586,6 @@ internal string UpdateStationConfig(IHttpContext context) cumulus.StationOptions.Humidity98Fix = settings.Options.use100for98hum; cumulus.StationOptions.CalculatedDP = settings.Options.calculatedewpoint; cumulus.StationOptions.CalculatedWC = settings.Options.calculatewindchill; - cumulus.StationOptions.SyncTime = settings.Options.syncstationclock; - cumulus.StationOptions.ClockSettingHour = settings.Options.syncclockhour; cumulus.StationOptions.UseCumulusPresstrendstr = settings.Options.cumuluspresstrendnames; cumulus.StationOptions.LogExtraSensors = settings.Options.extrasensors; cumulus.StationOptions.WS2300IgnoreStationClock = settings.Options.ignorelacrosseclock; @@ -626,13 +624,31 @@ internal string UpdateStationConfig(IHttpContext context) { if (settings.davisvp2 != null) { - cumulus.DavisOptions.ReadReceptionStats = settings.davisvp2.readreceptionstats; - cumulus.DavisOptions.SetLoggerInterval = settings.davisvp2.setloggerinterval; + cumulus.DavisOptions.ConnectionType = settings.davisvp2.davisconn.conntype; + if (settings.davisvp2.davisconn.tcpsettings != null) + { + cumulus.DavisOptions.IPAddr = settings.davisvp2.davisconn.tcpsettings.ipaddress ?? string.Empty; + cumulus.DavisOptions.PeriodicDisconnectInterval = settings.davisvp2.davisconn.tcpsettings.disconperiod; + } + cumulus.DavisOptions.ReadReceptionStats = settings.davisvp2.advanced.readreceptionstats; + cumulus.DavisOptions.SetLoggerInterval = settings.davisvp2.advanced.setloggerinterval; cumulus.DavisOptions.UseLoop2 = settings.davisvp2.advanced.useloop2; cumulus.DavisOptions.ForceVPBarUpdate = settings.davisvp2.advanced.vp1minbarupdate; - cumulus.DavisOptions.InitWaitTime = settings.davisvp2.advanced.initwaittime; - cumulus.DavisOptions.IPResponseTime = settings.davisvp2.advanced.ipresponsetime; - cumulus.DavisOptions.BaudRate = settings.davisvp2.advanced.baudrate; + cumulus.DavisOptions.RainGaugeType = settings.davisvp2.advanced.raingaugetype; + cumulus.StationOptions.SyncTime = settings.davisvp2.advanced.syncstationclock; + cumulus.StationOptions.ClockSettingHour = settings.davisvp2.advanced.syncclockhour; + if (cumulus.DavisOptions.ConnectionType == 0) + { + cumulus.ComportName = settings.davisvp2.davisconn.comportname; + cumulus.DavisOptions.BaudRate = settings.davisvp2.advanced.baudrate; + } + else // TCP/IP + { + cumulus.DavisOptions.InitWaitTime = settings.davisvp2.advanced.initwaittime; + cumulus.DavisOptions.IPResponseTime = settings.davisvp2.advanced.ipresponsetime; + cumulus.DavisOptions.TCPPort = settings.davisvp2.advanced.tcpport; + } + } } catch (Exception ex) @@ -648,7 +664,10 @@ internal string UpdateStationConfig(IHttpContext context) { if (settings.daviswll != null) { + cumulus.DavisOptions.ConnectionType = 2; // Always TCP/IP for WLL cumulus.WLLAutoUpdateIpAddress = settings.daviswll.network.autoDiscover; + cumulus.DavisOptions.IPAddr = settings.daviswll.network.ipaddress ?? string.Empty; + cumulus.WllApiKey = settings.daviswll.api.apiKey; cumulus.WllApiSecret = settings.daviswll.api.apiSecret; cumulus.WllStationId = settings.daviswll.api.apiStationId; @@ -699,6 +718,9 @@ internal string UpdateStationConfig(IHttpContext context) cumulus.WllExtraHumTx[5] = settings.daviswll.extraTemp.extraHumTx6; cumulus.WllExtraHumTx[6] = settings.daviswll.extraTemp.extraHumTx7; cumulus.WllExtraHumTx[7] = settings.daviswll.extraTemp.extraHumTx8; + + cumulus.DavisOptions.RainGaugeType = settings.daviswll.advanced.raingaugetype; + cumulus.DavisOptions.TCPPort = settings.daviswll.advanced.tcpport; } } catch (Exception ex) @@ -722,43 +744,6 @@ internal string UpdateStationConfig(IHttpContext context) context.Response.StatusCode = 500; } - - // com port - try - { - cumulus.ComportName = settings.general.comportname ?? cumulus.ComportName; - } - catch (Exception ex) - { - var msg = "Error processing COM port setting: " + ex.Message; - cumulus.LogMessage(msg); - errorMsg += msg + "\n\n"; - context.Response.StatusCode = 500; - } - - // Davis Common details - try - { - if (settings.daviscommon != null) - { - cumulus.DavisOptions.ConnectionType = settings.daviscommon.davisconn.conntype; - if (settings.daviscommon.davisconn.tcpsettings != null) - { - cumulus.DavisOptions.IPAddr = settings.daviscommon.davisconn.tcpsettings.ipaddress ?? string.Empty; - cumulus.DavisOptions.TCPPort = settings.daviscommon.davisconn.tcpsettings.tcpport; - cumulus.DavisOptions.PeriodicDisconnectInterval = settings.daviscommon.davisconn.tcpsettings.disconperiod; - cumulus.DavisOptions.RainGaugeType = settings.daviscommon.advanced.raingaugetype; - } - } - } - catch (Exception ex) - { - var msg = "Error processing Davis settings: " + ex.Message; - cumulus.LogMessage(msg); - errorMsg += msg + "\n\n"; - context.Response.StatusCode = 500; - } - // GW1000 connection details try { @@ -823,7 +808,10 @@ internal string UpdateStationConfig(IHttpContext context) { if (settings.imet != null) { + cumulus.ComportName = settings.imet.comportname ?? cumulus.ComportName; cumulus.ImetOptions.ImetBaudRate = settings.imet.baudrate; + cumulus.StationOptions.SyncTime = settings.imet.advanced.syncstationclock; + cumulus.StationOptions.ClockSettingHour = settings.imet.advanced.syncclockhour; cumulus.ImetOptions.ImetReadDelay = settings.imet.advanced.readdelay; cumulus.ImetOptions.ImetWaitTime = settings.imet.advanced.waittime; cumulus.ImetOptions.ImetUpdateLogPointer = settings.imet.advanced.updatelogpointer; @@ -1029,7 +1017,6 @@ internal class JsonStationSettingsData { public int stationid { get; set; } public JsonStationGeneral general { get; set; } - public JsonStationSettingsDavisCommon daviscommon { set; get; } public JsonStationSettingsDavisVp2 davisvp2 { get; set; } public JSonStationSettingsGw1000Conn gw1000 { get; set; } public JsonStationSettingsWLL daviswll { get; set; } @@ -1046,7 +1033,6 @@ internal class JsonStationSettingsData internal class JsonStationGeneral { public int stationtype { get; set; } - public string comportname { get; set; } public int loginterval { get; set; } public JsonStationSettingsLogRollover logrollover { get; set; } public JsonStationSettingsUnits units { get; set; } @@ -1092,8 +1078,6 @@ internal class JsonStationSettingsOptions public bool use100for98hum { get; set; } public bool calculatedewpoint { get; set; } public bool calculatewindchill { get; set; } - public bool syncstationclock { get; set; } - public int syncclockhour { get; set; } public bool cumuluspresstrendnames { get; set; } public bool roundwindspeeds { get; set; } public bool ignorelacrosseclock { get; set; } @@ -1108,41 +1092,37 @@ internal class JsonStationSettingsOptions internal class JsonStationSettingsTCPsettings { public string ipaddress { get; set; } - public int tcpport { get; set; } public int disconperiod { get; set; } } - internal class JsonStationSettingsDavisCommon - { - public JsonStationSettingsDavisConn davisconn { get; set; } - public JsonStationSettingsDavisCommonAdvanced advanced { get; set; } - } - - internal class JsonStationSettingsDavisConn + internal class JsonStationSettingsDavisVp2Connection { public int conntype { get; set; } + public string comportname { get; set; } public JsonStationSettingsTCPsettings tcpsettings { get; set; } } - internal class JsonStationSettingsDavisCommonAdvanced - { - public int raingaugetype { get; set; } - } - internal class JsonStationSettingsDavisVp2 { - public bool readreceptionstats { get; set; } - public bool setloggerinterval { get; set; } + public JsonStationSettingsDavisVp2Connection davisconn { get; set; } + public JsonStationSettingsDavisVp2Advanced advanced { get; set; } } internal class JsonStationSettingsDavisVp2Advanced { + public bool syncstationclock { get; set; } + public int syncclockhour { get; set; } + public bool readreceptionstats { get; set; } + public bool setloggerinterval { get; set; } public bool useloop2 { get; set; } + public int raingaugetype { get; set; } public bool vp1minbarupdate { get; set; } public int initwaittime { get; set; } public int ipresponsetime { get; set; } public int baudrate { get; set; } + public int tcpport { get; set; } + } internal class JsonStationSettingsFineOffsetAdvanced @@ -1178,12 +1158,16 @@ internal class JSonStationSettingsGw1000Conn internal class JsonStationSettingsImet { + public string comportname { get; set; } + public int baudrate { get; set; } public JsonStationSettingsImetAdvanced advanced { get; set; } } internal class JsonStationSettingsImetAdvanced { + public bool syncstationclock { get; set; } + public int syncclockhour { get; set; } public int waittime { get; set; } public int readdelay { get; set; } public bool updatelogpointer { get; set; } @@ -1239,11 +1223,20 @@ internal class JsonStationSettingsWLL public JsonStationSettingsWllPrimary primary { get; set; } public JsonStationSettingsWllSoilLeaf soilLeaf { get; set; } public JsonStationSettingsWllExtraTemp extraTemp { get; set; } + public JsonStationSettingsWLLAdvanced advanced { get; set; } + } + + public class JsonStationSettingsWLLAdvanced + { + public int raingaugetype { get; set; } + public int tcpport { get; set; } } internal class JsonStationSettingsWLLNetwork { public bool autoDiscover { get; set; } + public string ipaddress { get; set; } + } internal class JsonStationSettingsWLLApi diff --git a/Updates.txt b/Updates.txt index f7d145bd..b0994c7b 100644 --- a/Updates.txt +++ b/Updates.txt @@ -1,7 +1,8 @@ -3.10.0 - b310x +3.10.0 - b3110 —————————————— - Fix: Catch error creating System Uptime counter on Windows - Fix: The Local web server is now brought up before initialising the station. This allows you to correct a misconfigured station without resorting to editing the Cumulus.ini file. +- Fix: Diary Editor creating entries on the wrong day - New: The previous Console log file is now copied to an "-old" file on start-up @@ -17,6 +18,8 @@ - Change: The various charting pages now hide buttons for graphs that do not contain any data - both on the dashboard and default web site. - Change: Creation of the wxnow.txt file is now disabled by default for new installs - Change: Clock sync (Davis VP2 & Instromet) now occurs at 2 minutes past the hour selected +- Change: Davis VP/VP2/Vue ReadReceptionStats now defaults to enabled for new installs +- Change: The default output file format is now UTF-8 for new installs 3.9.7 - b3107 From e5b3710ec761857eb3ea045af481291ac755d985 Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Mon, 15 Feb 2021 23:17:03 +0000 Subject: [PATCH 06/12] b3111 --- CumulusMX/Cumulus.cs | 8 +++-- CumulusMX/DavisStation.cs | 15 ++++++-- CumulusMX/DavisWllStation.cs | 53 ++++++++++++++++++++++++++-- CumulusMX/InternetSettings.cs | 5 +-- CumulusMX/Properties/AssemblyInfo.cs | 6 ++-- CumulusMX/WeatherStation.cs | 31 ++++++++++------ CumulusMX/webtags.cs | 4 +-- Updates.txt | 1 + 8 files changed, 98 insertions(+), 25 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index c5adabc1..cd5db0d1 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -3419,6 +3419,10 @@ private void ReadIniFile() //DavisCalcAltPress = ini.GetValue("Station", "DavisCalcAltPress", true); //DavisConsoleHighGust = ini.GetValue("Station", "DavisConsoleHighGust", false); DavisOptions.RainGaugeType = ini.GetValue("Station", "VPrainGaugeType", -1); + if (DavisOptions.RainGaugeType > 3) + { + DavisOptions.RainGaugeType = -1; + } DavisOptions.ConnectionType = ini.GetValue("Station", "VP2ConnectionType", VP2SERIALCONNECTION); DavisOptions.TCPPort = ini.GetValue("Station", "VP2TCPPort", 22222); DavisOptions.IPAddr = ini.GetValue("Station", "VP2IPAddr", "0.0.0.0"); @@ -8453,11 +8457,11 @@ public void RealtimeFTPDisconnect() { try { - if (Sslftp == FtpProtocols.SFTP) + if (Sslftp == FtpProtocols.SFTP && RealtimeSSH != null) { RealtimeSSH.Disconnect(); } - else + else if (RealtimeFTP != null) { RealtimeFTP.Disconnect(); } diff --git a/CumulusMX/DavisStation.cs b/CumulusMX/DavisStation.cs index cf3d52e5..6937327e 100644 --- a/CumulusMX/DavisStation.cs +++ b/CumulusMX/DavisStation.cs @@ -3720,19 +3720,28 @@ internal double ConvertRainClicksToInternal(double clicks) /// private double ConvertRainClicksToUser(double clicks) { - // One click is either 0.01 inches or 0.2 mm + // One click is either 0.01, 0.001 inches or 0.2, 0.1 mm switch (cumulus.DavisOptions.RainGaugeType) { case 0: - // Rain gauge is metric, convert to user unit + // Rain gauge is metric 0.2 mm return ConvertRainMMToUser(clicks * 0.2); case 1: - // Rain gauge is imperial, convert to user unit + // Rain gauge is imperial 0.01 in return ConvertRainINToUser(clicks * 0.01); + case 2: + // Rain gauge is metric 0.1 mm + return ConvertRainMMToUser(clicks * 0.1); + + case 3: + // Rain gauge is imperial 0.001 in + return ConvertRainMMToUser(clicks * 0.2); + default: // Rain gauge type not configured, assume it is the same as the station units + // Assume standard gauge type of 0.01 in or 0.02 mm return cumulus.Units.Rain == 0 ? clicks * 0.2 : clicks * 0.01; } } diff --git a/CumulusMX/DavisWllStation.cs b/CumulusMX/DavisWllStation.cs index fb052aa4..58ff6a58 100644 --- a/CumulusMX/DavisWllStation.cs +++ b/CumulusMX/DavisWllStation.cs @@ -221,8 +221,15 @@ public override void Start() if (port == 0) { cumulus.LogMessage("WLL failed to get broadcast port via realtime request, defaulting to 22222"); - port = 22222; + port = cumulus.DavisOptions.TCPPort; } + else if (port != cumulus.DavisOptions.TCPPort) + { + cumulus.LogMessage($"WLL Discovered broacast port ({port}) is not the same as in the config ({cumulus.DavisOptions.TCPPort}), resetting config to match"); + cumulus.DavisOptions.TCPPort = port; + cumulus.WriteIniFile(); + } + // Create a broadcast listener Task.Run(() => { @@ -774,7 +781,7 @@ private void DecodeCurrent(string currentJson) { /* * Available fields: - * rec["rain_size"] + * rec["rain_size"] - 0: Reseverved, 1: 0.01", 2: 0.2mm, 3: 0.1mm, 4: 0.001" * rec["rain_rate_last"], rec["rain_rate_hi"] * rec["rainfall_last_15_min"], rec["rain_rate_hi_last_15_min"] * rec["rainfall_last_60_min"] @@ -789,6 +796,43 @@ private void DecodeCurrent(string currentJson) cumulus.LogDebugMessage($"WLL current: using rain data from TxId {data1.txid}"); + var tipSize = data1.rain_size; + switch (tipSize) + { + case 1: + if (cumulus.DavisOptions.RainGaugeType != 1) + { + cumulus.LogMessage($"Setting Davis rain tipper size - was {cumulus.DavisOptions.RainGaugeType}, now 1 = 0.01 in"); + cumulus.DavisOptions.RainGaugeType = 1; + cumulus.WriteIniFile(); + } + break; + case 2: + if (cumulus.DavisOptions.RainGaugeType != 0) + { + cumulus.LogMessage($"Setting Davis rain tipper size - was {cumulus.DavisOptions.RainGaugeType}, now 0 = 0.2 mm"); + cumulus.DavisOptions.RainGaugeType = 0; + cumulus.WriteIniFile(); + } + break; + case 3: + if (cumulus.DavisOptions.RainGaugeType != 2) + { + cumulus.LogMessage($"Setting Davis rain tipper size - was {cumulus.DavisOptions.RainGaugeType}, now 0 = 0.1 mm"); + cumulus.DavisOptions.RainGaugeType = 2; + cumulus.WriteIniFile(); + } + break; + case 4: + if (cumulus.DavisOptions.RainGaugeType != 3) + { + cumulus.LogMessage($"Setting Davis rain tipper size - was {cumulus.DavisOptions.RainGaugeType}, now 0 = 0.001 in"); + cumulus.DavisOptions.RainGaugeType = 2; + cumulus.WriteIniFile(); + } + break; + } + // Rain data can be a bit out of date compared to the broadcasts (1 minute update), so only use storm data // All rainfall values supplied as *tip counts* @@ -1733,6 +1777,11 @@ private void DecodeHistoric(int dataType, int sensorType, string json) DoOutdoorTemp(ConvertTempFToUser(data11.temp_lo), ts); // do last temp DoOutdoorTemp(ConvertTempFToUser(data11.temp_last), recordTs); + + // set the values for daily average, arch_int is in seconds + tempsamplestoday += data11.arch_int / 60; + TempTotalToday += ConvertTempFToUser(data11.temp_avg) * data11.arch_int / 60; + } } catch (Exception ex) diff --git a/CumulusMX/InternetSettings.cs b/CumulusMX/InternetSettings.cs index e1754726..69161a42 100644 --- a/CumulusMX/InternetSettings.cs +++ b/CumulusMX/InternetSettings.cs @@ -434,9 +434,10 @@ public string UpdateInternetConfig(IHttpContext context) cumulus.MoonImageEnabled = settings.moonimage.enabled; if (cumulus.MoonImageEnabled) { - cumulus.IncludeMoonImage = settings.moonimage.includemoonimage; cumulus.MoonImageSize = settings.moonimage.size; - cumulus.MoonImageFtpDest = settings.moonimage.ftpdest; + cumulus.IncludeMoonImage = settings.moonimage.includemoonimage; + if (cumulus.IncludeMoonImage) + cumulus.MoonImageFtpDest = settings.moonimage.ftpdest; } } catch (Exception ex) diff --git a/CumulusMX/Properties/AssemblyInfo.cs b/CumulusMX/Properties/AssemblyInfo.cs index d80049c6..4bf8eb5c 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("Build 3110")] +[assembly: AssemblyDescription("Build 3111")] [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.10.0.3110")] -[assembly: AssemblyFileVersion("3.10.0.3110")] +[assembly: AssemblyVersion("3.10.0.3111")] +[assembly: AssemblyFileVersion("3.10.0.3111")] diff --git a/CumulusMX/WeatherStation.cs b/CumulusMX/WeatherStation.cs index 9da38e12..0073e4e8 100644 --- a/CumulusMX/WeatherStation.cs +++ b/CumulusMX/WeatherStation.cs @@ -3403,21 +3403,30 @@ public void DoRain(double total, double rate, DateTime timestamp) var previoustotal = Raincounter; - double raintipthreshold; + double raintipthreshold = 0; ; if (cumulus.Manufacturer == cumulus.DAVIS) // Davis can have either 0.2mm or 0.01in buckets, and the user could select to measure in mm or inches! { // If the bucket size is set, use that, otherwise infer from rain units var bucketSize = cumulus.DavisOptions.RainGaugeType == -1 ? cumulus.Units.Rain : cumulus.DavisOptions.RainGaugeType; - if (bucketSize == 0) // 0.2 mm tips + switch (bucketSize) { - // mm/mm (0.2) or mm/in (0.00787) - raintipthreshold = cumulus.Units.Rain == 0 ? 0.19 : 0.006; - } - else // 0.01 inch tips - { - // in/mm (0.254) or in/in (0.01) - raintipthreshold = cumulus.Units.Rain == 0 ? 0.2 : 0.009; + case 0: // 0.2 mm tips + // mm/mm (0.2) or mm/in (0.00787) + raintipthreshold = cumulus.Units.Rain == 0 ? 0.19 : 0.006; + break; + case 1: // 0.01 inch tips + // in/mm (0.254) or in/in (0.01) + raintipthreshold = cumulus.Units.Rain == 0 ? 0.2 : 0.009; + break; + case 2: // 0.01 mm tips + // mm/mm (0.1) or mm/in (0.0394) + raintipthreshold = cumulus.Units.Rain == 0 ? 0.09 : 0.003; + break; + case 3: // 0.001 inch tips + // in/mm (0.0254) or in/in (0.001) + raintipthreshold = cumulus.Units.Rain == 0 ? 0.02 : 0.0009; + break; } } else @@ -10129,7 +10138,7 @@ internal string GetDiaryData(string date) StringBuilder json = new StringBuilder("{\"entry\":\"", 1024); - var result = cumulus.DiaryDB.Query("select * from DiaryData where date(Timestamp) = ? order by Timestamp limit 1", date); + var result = cumulus.DiaryDB.Query("select * from DiaryData where date(Timestamp,'utc') = ? order by Timestamp limit 1", date); if (result.Count > 0) { @@ -10164,7 +10173,7 @@ internal string GetDiarySummary() for (int i = 0; i < result.Count; i++) { json.Append("\""); - json.Append(result[i].Timestamp.ToString("yyy-MM-dd")); + json.Append(result[i].Timestamp.ToUniversalTime().ToString("yyy-MM-dd")); json.Append("\","); } json.Remove(json.Length - 1, 1); diff --git a/CumulusMX/webtags.cs b/CumulusMX/webtags.cs index ff2f32e6..b312620d 100644 --- a/CumulusMX/webtags.cs +++ b/CumulusMX/webtags.cs @@ -2867,7 +2867,7 @@ private string Tagforum(Dictionary tagParams) return string.Empty; } - return $":forum:"; + return $":forum:"; } private string Tagwebcam(Dictionary tagParams) @@ -2877,7 +2877,7 @@ private string Tagwebcam(Dictionary tagParams) return string.Empty; } - return @":webcam:"; + return @":webcam:"; } private string Tagtempunit(Dictionary tagParams) diff --git a/Updates.txt b/Updates.txt index b0994c7b..7986af0b 100644 --- a/Updates.txt +++ b/Updates.txt @@ -3,6 +3,7 @@ - Fix: Catch error creating System Uptime counter on Windows - Fix: The Local web server is now brought up before initialising the station. This allows you to correct a misconfigured station without resorting to editing the Cumulus.ini file. - Fix: Diary Editor creating entries on the wrong day +- Fix: WLL day average temp stats on historic catch-up - New: The previous Console log file is now copied to an "-old" file on start-up From 286c629ccc24e4274a89941d340f2a77b304dd75 Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Tue, 16 Feb 2021 22:53:51 +0000 Subject: [PATCH 07/12] b3112 - fix gw1000 auto discovery --- CumulusMX/GW1000Station.cs | 18 +++++++++++------- CumulusMX/Properties/AssemblyInfo.cs | 6 +++--- Updates.txt | 5 +++-- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/CumulusMX/GW1000Station.cs b/CumulusMX/GW1000Station.cs index 8634963a..bb1cce8e 100644 --- a/CumulusMX/GW1000Station.cs +++ b/CumulusMX/GW1000Station.cs @@ -505,16 +505,20 @@ private bool DoDiscovery() } else if (discoveredDevices.IP.Count == 1 && (string.IsNullOrEmpty(macaddr) || discoveredDevices.Mac[0] == macaddr)) { + cumulus.LogDebugMessage("Discovered one GW1000 device"); // If only one device is discovered, and its MAC address matches (or our MAC is blank), then just use it - cumulus.LogMessage("Discovered a new IP address for the GW1000 that does not match our current one"); - cumulus.LogMessage($"Changing previous IP address: {ipaddr} to {discoveredDevices.IP[0]}"); - ipaddr = discoveredDevices.IP[0]; - cumulus.Gw1000IpAddress = ipaddr; - if (discoveredDevices.Mac[0] != macaddr) + if (cumulus.Gw1000IpAddress != discoveredDevices.IP[0]) { - cumulus.Gw1000MacAddress = discoveredDevices.Mac[0]; + cumulus.LogMessage("Discovered a new IP address for the GW1000 that does not match our current one"); + cumulus.LogMessage($"Changing previous IP address: {ipaddr} to {discoveredDevices.IP[0]}"); + ipaddr = discoveredDevices.IP[0].Trim(); + cumulus.Gw1000IpAddress = ipaddr; + if (discoveredDevices.Mac[0] != macaddr) + { + cumulus.Gw1000MacAddress = discoveredDevices.Mac[0]; + } + cumulus.WriteIniFile(); } - cumulus.WriteIniFile(); } else if (discoveredDevices.Mac.Contains(macaddr)) { diff --git a/CumulusMX/Properties/AssemblyInfo.cs b/CumulusMX/Properties/AssemblyInfo.cs index 4bf8eb5c..96a7942a 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("Build 3111")] +[assembly: AssemblyDescription("Build 3112")] [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.10.0.3111")] -[assembly: AssemblyFileVersion("3.10.0.3111")] +[assembly: AssemblyVersion("3.10.0.3112")] +[assembly: AssemblyFileVersion("3.10.0.3112")] diff --git a/Updates.txt b/Updates.txt index 7986af0b..60037420 100644 --- a/Updates.txt +++ b/Updates.txt @@ -1,9 +1,10 @@ -3.10.0 - b3110 +3.10.0 - b3112 —————————————— - Fix: Catch error creating System Uptime counter on Windows - Fix: The Local web server is now brought up before initialising the station. This allows you to correct a misconfigured station without resorting to editing the Cumulus.ini file. -- Fix: Diary Editor creating entries on the wrong day +- Fix: Diary Editor creating entries on the wrong day, and revamp the interface a bit - Fix: WLL day average temp stats on historic catch-up +- Fix: GW1000 auto-discovery was triggering an erroneous IP address change - New: The previous Console log file is now copied to an "-old" file on start-up From 5900316cc623d05e66d6444238da336bfb27b839 Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Fri, 19 Feb 2021 15:48:51 +0000 Subject: [PATCH 08/12] b3112 NOAA file format fix on read, wl.com status reads, new web tags for default web site --- CumulusMX/Cumulus.cs | 18 +++--- CumulusMX/DataEditor.cs | 1 - CumulusMX/DavisWllStation.cs | 110 +++++++++++++++++++++++++++++++++ CumulusMX/NOAA.cs | 8 ++- CumulusMX/NOAAReports.cs | 4 +- CumulusMX/WeatherLinkDotCom.cs | 38 +++++++++++- CumulusMX/webtags.cs | 22 +++++++ Updates.txt | 4 ++ 8 files changed, 188 insertions(+), 17 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index cd5db0d1..eeeda15b 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -4201,47 +4201,47 @@ private void ReadIniFile() NOAAstate = ini.GetValue("NOAA", "State", " "); NOAA12hourformat = ini.GetValue("NOAA", "12hourformat", false); NOAAheatingthreshold = ini.GetValue("NOAA", "HeatingThreshold", -1000.0); - if (NOAAheatingthreshold < -999) + if (NOAAheatingthreshold < -99 || NOAAheatingthreshold > 150) { NOAAheatingthreshold = Units.Temp == 0 ? 18.3 : 65; } NOAAcoolingthreshold = ini.GetValue("NOAA", "CoolingThreshold", -1000.0); - if (NOAAcoolingthreshold < -999) + if (NOAAcoolingthreshold < -99 || NOAAcoolingthreshold > 150) { NOAAcoolingthreshold = Units.Temp == 0 ? 18.3 : 65; } NOAAmaxtempcomp1 = ini.GetValue("NOAA", "MaxTempComp1", -1000.0); - if (NOAAmaxtempcomp1 < -999) + if (NOAAmaxtempcomp1 < -99 || NOAAmaxtempcomp1 > 150) { NOAAmaxtempcomp1 = Units.Temp == 0 ? 27 : 80; } NOAAmaxtempcomp2 = ini.GetValue("NOAA", "MaxTempComp2", -1000.0); - if (NOAAmaxtempcomp2 < -999) + if (NOAAmaxtempcomp2 < -99 || NOAAmaxtempcomp2 > 99) { NOAAmaxtempcomp2 = Units.Temp == 0 ? 0 : 32; } NOAAmintempcomp1 = ini.GetValue("NOAA", "MinTempComp1", -1000.0); - if (NOAAmintempcomp1 < -999) + if (NOAAmintempcomp1 < -99 || NOAAmintempcomp1 > 99) { NOAAmintempcomp1 = Units.Temp == 0 ? 0 : 32; } NOAAmintempcomp2 = ini.GetValue("NOAA", "MinTempComp2", -1000.0); - if (NOAAmintempcomp2 < -999) + if (NOAAmintempcomp2 < -99 || NOAAmintempcomp2 > 99) { NOAAmintempcomp2 = Units.Temp == 0 ? -18 : 0; } NOAAraincomp1 = ini.GetValue("NOAA", "RainComp1", -1000.0); - if (NOAAraincomp1 < -999) + if (NOAAraincomp1 < 0 || NOAAraincomp1 > 99) { NOAAraincomp1 = Units.Rain == 0 ? 0.2 : 0.01; } NOAAraincomp2 = ini.GetValue("NOAA", "RainComp2", -1000.0); - if (NOAAraincomp2 < -999) + if (NOAAraincomp2 < 0 || NOAAraincomp2 > 99) { NOAAraincomp2 = Units.Rain == 0 ? 2 : 0.1; } NOAAraincomp3 = ini.GetValue("NOAA", "RainComp3", -1000.0); - if (NOAAraincomp3 < -999) + if (NOAAraincomp3 < 0 || NOAAraincomp3 > 99) { NOAAraincomp3 = Units.Rain == 0 ? 20 : 1; } diff --git a/CumulusMX/DataEditor.cs b/CumulusMX/DataEditor.cs index f4931cd8..b00445a1 100644 --- a/CumulusMX/DataEditor.cs +++ b/CumulusMX/DataEditor.cs @@ -47,7 +47,6 @@ internal DataEditor(Cumulus cumulus) return DateTime.MinValue; }; - } internal void SetStation(WeatherStation station) diff --git a/CumulusMX/DavisWllStation.cs b/CumulusMX/DavisWllStation.cs index 58ff6a58..e36e1ad1 100644 --- a/CumulusMX/DavisWllStation.cs +++ b/CumulusMX/DavisWllStation.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.Globalization; using System.IO.Ports; using System.Linq; using System.Net; @@ -55,6 +56,34 @@ public DavisWllStation(Cumulus cumulus) : base(cumulus) cumulus.LogMessage("Station type = Davis WLL"); + // Override the ServiceStack Deserialization function + // Check which format provided, attempt to parse as datetime or return minValue. + // Formats to use for the different date kinds + string utcTimeFormat = "yyyy-MM-dd'T'HH:mm:ss.fff'Z'"; + string localTimeFormat = "yyyy-MM-dd'T'HH:mm:ss"; + + + ServiceStack.Text.JsConfig.DeSerializeFn = datetimeStr => + { + if (string.IsNullOrWhiteSpace(datetimeStr)) + { + return DateTime.MinValue; + } + + if (datetimeStr.EndsWith("Z") && + DateTime.TryParseExact(datetimeStr, utcTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out DateTime resultUtc)) + { + return resultUtc; + } + else if (!datetimeStr.EndsWith("Z") && + DateTime.TryParseExact(datetimeStr, localTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out DateTime resultLocal)) + { + return resultLocal; + } + + return DateTime.MinValue; + }; + tmrRealtime = new System.Timers.Timer(); tmrCurrent = new System.Timers.Timer(); tmrBroadcastWatchdog = new System.Timers.Timer(); @@ -112,6 +141,11 @@ public DavisWllStation(Cumulus cumulus) : base(cumulus) useWeatherLinkDotCom = false; } + if (useWeatherLinkDotCom) + { + // Get wl.com status + GetSystemStatus(); + } // Perform Station ID checks - If we have API deatils! // If the Station ID is missing, this will populate it if the user only has one station associated with the API key @@ -2579,6 +2613,8 @@ private void GetWlHistoricHealth() { var errObj = responseBody.FromJson(); cumulus.LogMessage($"WLL Health: WeatherLink API Error: {errObj.code}, {errObj.message}"); + // Get wl.com status + GetSystemStatus(); return; } @@ -2586,6 +2622,8 @@ private void GetWlHistoricHealth() { cumulus.LogMessage("WLL Health: WeatherLink API: No data was returned. Check your Device Id."); cumulus.LastUpdateTime = Utils.FromUnixTime(endTime); + // Get wl.com status + GetSystemStatus(); return; } @@ -2922,6 +2960,78 @@ private int GetWlHistoricHealthLsid(int id, int type) return 0; } + private void GetSystemStatus() + { + var status = new WlComSystemStatus(); + try + { + string responseBody; + int responseCode; + + cumulus.LogDebugMessage("GetSystemStatus: Getting WeatherLink.com system status"); + + // we want to do this synchronously, so .Result + using (HttpResponseMessage response = wlHttpClient.GetAsync("https://0886445102835570.hostedstatus.com/1.0/status/600712dea9c1290530967bc6").Result) + { + responseBody = responseBody = response.Content.ReadAsStringAsync().Result; + responseCode = (int)response.StatusCode; + cumulus.LogDebugMessage($"GetSystemStatus: WeatherLink.com system status Response code: {responseCode}"); + cumulus.LogDataMessage($"GetSystemStatus: WeatherLink.com system status Response: {responseBody}"); + } + + if (responseCode != 200) + { + cumulus.LogMessage($"GetSystemStatus: WeatherLink.com system status Error: {responseCode}"); + cumulus.LogConsoleMessage($" - Error {responseCode}"); + return; + } + + status = responseBody.FromJson(); + + if (responseBody == "{}") + { + cumulus.LogMessage("GetSystemStatus: WeatherLink.com system status: No data was returned."); + return; + } + else if (status != null) + { + var msg = $"Weatherlink.com overall System Status: '{status.result.status_overall.status}', Updated: {status.result.status_overall.updated}"; + if (status.result.status_overall.status_code != 100) + { + msg += "Error: "; + cumulus.LogMessage(msg); + Console.WriteLine(msg); + } + else + { + cumulus.LogDebugMessage(msg); + } + // If we are not OK, then find what isn't working + if (status.result.status_overall.status_code != 100) + { + foreach (var subSys in status.result.status) + { + msg = $" wl.com system: {subSys.name}, status: {subSys.status}, updated: {subSys.updated}"; + cumulus.LogMessage(msg); + Console.WriteLine(msg); + } + } + } + else + { + cumulus.LogMessage("GetSystemStatus: Something went wrong!"); + } + + } + catch (Exception ex) + { + cumulus.LogMessage("GetSystemStatus: Exception: " + ex); + return; + } + + return; + } + private class WllBroadcast { public string did { get; set; } diff --git a/CumulusMX/NOAA.cs b/CumulusMX/NOAA.cs index 6a667777..f8f51b9b 100644 --- a/CumulusMX/NOAA.cs +++ b/CumulusMX/NOAA.cs @@ -294,7 +294,7 @@ public List CreateMonthlyReport(DateTime thedate) { // read hdd from dayfile.txt dayList[daynumber].heatingdegdays = double.Parse(st[idx]); - totalheating += double.Parse(st[40]); + totalheating += double.Parse(st[idx]); } else if (meantemp < cumulus.NOAAheatingthreshold) { @@ -357,7 +357,8 @@ public List CreateMonthlyReport(DateTime thedate) // min temp idx = 4; dayList[daynumber].mintemp = double.Parse(st[idx]); - timestr = st[5]; + idx = 5; + timestr = st[idx]; hour = Convert.ToInt32(timestr.Substring(0, 2)); minute = Convert.ToInt32(timestr.Substring(3, 2)); dayList[daynumber].mintemptimestamp = DateTime.MinValue.Date.Add(new TimeSpan(hour, minute, 0)); @@ -401,7 +402,8 @@ public List CreateMonthlyReport(DateTime thedate) // high wind speed idx = 1; dayList[daynumber].highwindspeed = double.Parse(st[idx]); - timestr = st[3]; + idx = 3; + timestr = st[idx]; hour = Convert.ToInt32(timestr.Substring(0, 2)); minute = Convert.ToInt32(timestr.Substring(3, 2)); dayList[daynumber].highwindtimestamp = DateTime.MinValue.Date.Add(new TimeSpan(hour, minute, 0)); diff --git a/CumulusMX/NOAAReports.cs b/CumulusMX/NOAAReports.cs index 4fad4b49..2179e3ed 100644 --- a/CumulusMX/NOAAReports.cs +++ b/CumulusMX/NOAAReports.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text; namespace CumulusMX { @@ -80,7 +81,8 @@ public List GetNoaaMonthReport(int year, int month) { var reportName = noaats.ToString(cumulus.NOAAMonthFileFormat); noaafile = cumulus.ReportPath + reportName; - report = File.Exists(noaafile) ? new List (File.ReadAllLines(noaafile)) : new List { "That report does not exist" }; + var encoding = cumulus.NOAAUseUTF8 ? Encoding.GetEncoding("utf-8") : Encoding.GetEncoding("iso-8859-1"); + report = File.Exists(noaafile) ? new List (File.ReadAllLines(noaafile, encoding)) : new List { "That report does not exist" }; } catch { diff --git a/CumulusMX/WeatherLinkDotCom.cs b/CumulusMX/WeatherLinkDotCom.cs index 980beb0c..d9ee2c11 100644 --- a/CumulusMX/WeatherLinkDotCom.cs +++ b/CumulusMX/WeatherLinkDotCom.cs @@ -315,8 +315,8 @@ public class WlHistorySensorDataType17 // Data Structure type 18 = AirLink Health record public class WlHistorySensorDataType18 { - public long? air_quality_firmware_version { get; set; } // OLD original incorrect name - public long? firmware_version { get; set; } // NEW correct name + public long? air_quality_firmware_version { get; set; } // OLD original incorrect name + public long? firmware_version { get; set; } // NEW correct name public string application_sha { get; set; } public string application_version { get; set; } public long bootloader_version { get; set; } @@ -357,7 +357,7 @@ public class WlSensorList { public List sensors { get; set; } public long generated_at { get; set; } -} + } public class WlSensorListSensor { @@ -430,4 +430,36 @@ public WlSensor(int sensorType, int lsid, int parentId, string name, string pare public string Name { get; set; } public string ParentName { get; set; } } + + + // WeatherLink.com status + public class WlComSystemStatus + { + public WlComSystemStatusResult result {get; set;} + } + + public class WlComSystemStatusResult + { + public WlComStatusOverall status_overall { get; set; } + public WlComStatus[] status { get; set; } + } + + public class WlComStatusOverall + { + public DateTime updated { get; set; } + public string status { get; set; } + public int status_code { get; set; } + } + + public class WlComStatus : WlComStatusContainer + { + public WlComStatusContainer[] containers { get; set; } + } + + public class WlComStatusContainer : WlComStatusOverall + { + public string id { get; set; } + public string name { get; set; } + } + } diff --git a/CumulusMX/webtags.cs b/CumulusMX/webtags.cs index b312620d..abdfe3d6 100644 --- a/CumulusMX/webtags.cs +++ b/CumulusMX/webtags.cs @@ -2870,6 +2870,16 @@ private string Tagforum(Dictionary tagParams) return $":forum:"; } + private string Tagforumurl(Dictionary tagParams) + { + if (string.IsNullOrEmpty(cumulus.ForumURL)) + { + return string.Empty; + } + + return cumulus.ForumURL; + } + private string Tagwebcam(Dictionary tagParams) { if (string.IsNullOrEmpty(cumulus.WebcamURL)) @@ -2879,6 +2889,16 @@ private string Tagwebcam(Dictionary tagParams) return @":webcam:"; } + private string Tagwebcamurl(Dictionary tagParams) + { + if (string.IsNullOrEmpty(cumulus.WebcamURL)) + { + return string.Empty; + } + + return cumulus.WebcamURL; + } + private string Tagtempunit(Dictionary tagParams) { @@ -5308,7 +5328,9 @@ public void InitialiseWebtags() { "chillhours", TagChillHours }, { "altitude", Tagaltitude }, { "forum", Tagforum }, + { "forumurl", Tagforumurl }, { "webcam", Tagwebcam }, + { "webcamurl", Tagwebcamurl }, { "tempunit", Tagtempunit }, { "tempunitnodeg", Tagtempunitnodeg }, { "windunit", Tagwindunit }, diff --git a/Updates.txt b/Updates.txt index 60037420..17b4d947 100644 --- a/Updates.txt +++ b/Updates.txt @@ -6,7 +6,11 @@ - Fix: WLL day average temp stats on historic catch-up - Fix: GW1000 auto-discovery was triggering an erroneous IP address change +- New: Brand new default web site template courtesy of Neil Thomas. The original "legacy" web site is still included, but it has been moved to the /webfiles-legacy folder. + - The new web site is now data file driven as opposed to all pages being processed and uploaded. The legacy web site has also been updated to use this method. - New: The previous Console log file is now copied to an "-old" file on start-up +- New: For Davis WLL stations using weatherlink.com, Cumulus now checks and reports the operational status of weatherlink.com on start-up and if an error occurs accessing the service +- New: Two web tags <#forumurl> and <#webcamurl>, which just return the respective URLs rather than the pre-canned HTML of <#forum> and <#webcam> - Change: All the settings screens revamped, reorganised and extended. - Many of the settings are now context sensitive, only showing items relevant to your station and configuration. From 1949a096ccb05f422153bb160df163aac45276f5 Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Sat, 20 Feb 2021 20:48:21 +0000 Subject: [PATCH 09/12] b3113 Fix weather diary again --- CumulusMX/AstroLib.cs | 4 +- CumulusMX/DataEditor.cs | 82 +++++++++++++++++++--------- CumulusMX/DavisWllStation.cs | 2 +- CumulusMX/Properties/AssemblyInfo.cs | 6 +- CumulusMX/WM918Station.cs | 4 +- CumulusMX/WMR928Station.cs | 4 +- CumulusMX/WS2300Station.cs | 3 +- Updates.txt | 2 +- 8 files changed, 64 insertions(+), 43 deletions(-) diff --git a/CumulusMX/AstroLib.cs b/CumulusMX/AstroLib.cs index 2e2784d6..66d457b2 100644 --- a/CumulusMX/AstroLib.cs +++ b/CumulusMX/AstroLib.cs @@ -63,11 +63,9 @@ private static double RadToDeg(double angle) public static double SolarMax(DateTime timestamp, double longitude, double latitude, double altitude, out double solarelevation, double transfactor, double turbidity, int method) { - double az; - DateTime utctime = timestamp.ToUniversalTime(); - CalculateSunPosition(utctime, latitude, longitude, out solarelevation, out az); + CalculateSunPosition(utctime, latitude, longitude, out solarelevation, out _); var dEpoch = new DateTime(1990, 1, 1, 0, 0, 0); double erv = CalcSunDistance(utctime, dEpoch); diff --git a/CumulusMX/DataEditor.cs b/CumulusMX/DataEditor.cs index b00445a1..4b72dded 100644 --- a/CumulusMX/DataEditor.cs +++ b/CumulusMX/DataEditor.cs @@ -20,33 +20,6 @@ internal class DataEditor internal DataEditor(Cumulus cumulus) { this.cumulus = cumulus; - - // Formats to use for the different date kinds - string utcTimeFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"; - string localTimeFormat = "yyyy-MM-dd'T'HH:mm:ss"; - - // Override the ServiceStack Deserialization function - // Check which format provided, attempt to parse as datetime or return minValue. - ServiceStack.Text.JsConfig.DeSerializeFn = datetimeStr => - { - if (string.IsNullOrWhiteSpace(datetimeStr)) - { - return DateTime.MinValue; - } - - if (datetimeStr.EndsWith("Z") && - DateTime.TryParseExact(datetimeStr, utcTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out DateTime resultUtc)) - { - return resultUtc; - } - else if (!datetimeStr.EndsWith("Z") && - DateTime.TryParseExact(datetimeStr, localTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out DateTime resultLocal)) - { - return resultLocal; - } - - return DateTime.MinValue; - }; } internal void SetStation(WeatherStation station) @@ -113,6 +86,7 @@ internal string EditDiary(IHttpContext context) { try { + var request = context.Request; string text; @@ -121,6 +95,33 @@ internal string EditDiary(IHttpContext context) text = reader.ReadToEnd(); } + // Formats to use for the different date kinds + string utcTimeFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"; + string localTimeFormat = "yyyy-MM-dd'T'HH:mm:ss"; + + // Override the ServiceStack Deserialization function + // Check which format provided, attempt to parse as datetime or return minValue. + ServiceStack.Text.JsConfig.DeSerializeFn = datetimeStr => + { + if (string.IsNullOrWhiteSpace(datetimeStr)) + { + return DateTime.MinValue; + } + + if (datetimeStr.EndsWith("Z") && + DateTime.TryParseExact(datetimeStr, utcTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out DateTime resultUtc)) + { + return resultUtc; + } + else if (!datetimeStr.EndsWith("Z") && + DateTime.TryParseExact(datetimeStr, localTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out DateTime resultLocal)) + { + return resultLocal; + } + + return DateTime.MinValue; + }; + var newData = text.FromJson(); // write new/updated entry to the database @@ -148,6 +149,33 @@ internal string DeleteDiary(IHttpContext context) text = reader.ReadToEnd(); } + // Formats to use for the different date kinds + string utcTimeFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"; + string localTimeFormat = "yyyy-MM-dd'T'HH:mm:ss"; + + // Override the ServiceStack Deserialization function + // Check which format provided, attempt to parse as datetime or return minValue. + ServiceStack.Text.JsConfig.DeSerializeFn = datetimeStr => + { + if (string.IsNullOrWhiteSpace(datetimeStr)) + { + return DateTime.MinValue; + } + + if (datetimeStr.EndsWith("Z") && + DateTime.TryParseExact(datetimeStr, utcTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out DateTime resultUtc)) + { + return resultUtc; + } + else if (!datetimeStr.EndsWith("Z") && + DateTime.TryParseExact(datetimeStr, localTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out DateTime resultLocal)) + { + return resultLocal; + } + + return DateTime.MinValue; + }; + var record = text.FromJson(); // Delete the corresponding entry from the database diff --git a/CumulusMX/DavisWllStation.cs b/CumulusMX/DavisWllStation.cs index e36e1ad1..353f65e0 100644 --- a/CumulusMX/DavisWllStation.cs +++ b/CumulusMX/DavisWllStation.cs @@ -2962,7 +2962,7 @@ private int GetWlHistoricHealthLsid(int id, int type) private void GetSystemStatus() { - var status = new WlComSystemStatus(); + WlComSystemStatus status; try { string responseBody; diff --git a/CumulusMX/Properties/AssemblyInfo.cs b/CumulusMX/Properties/AssemblyInfo.cs index 96a7942a..2eacc3c5 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("Build 3112")] +[assembly: AssemblyDescription("Build 3113")] [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.10.0.3112")] -[assembly: AssemblyFileVersion("3.10.0.3112")] +[assembly: AssemblyVersion("3.10.0.3113")] +[assembly: AssemblyFileVersion("3.10.0.3113")] diff --git a/CumulusMX/WM918Station.cs b/CumulusMX/WM918Station.cs index 69f59f70..efb75bb1 100644 --- a/CumulusMX/WM918Station.cs +++ b/CumulusMX/WM918Station.cs @@ -241,9 +241,7 @@ private bool WM918valid(List s, out int csum) /// private void Parse(List buff) { - int csum; - - if (WM918valid(buff, out csum)) + if (WM918valid(buff, out _)) { DateTime now = DateTime.Now; diff --git a/CumulusMX/WMR928Station.cs b/CumulusMX/WMR928Station.cs index 931c44c3..793be565 100644 --- a/CumulusMX/WMR928Station.cs +++ b/CumulusMX/WMR928Station.cs @@ -206,8 +206,6 @@ private bool WMR928valid(List s, out int csum) // Validates a WMR928 packet private void Parse(List buff) { - int csum; - string msg = "Packet received: "; for (int i = 0; i < buff.Count; i++) @@ -215,7 +213,7 @@ private void Parse(List buff) msg += buff[i].ToString("X2"); } - if (WMR928valid(buff, out csum)) + if (WMR928valid(buff, out _)) { DateTime now = DateTime.Now; switch (buff[2]) diff --git a/CumulusMX/WS2300Station.cs b/CumulusMX/WS2300Station.cs index 349ace36..86e597ec 100644 --- a/CumulusMX/WS2300Station.cs +++ b/CumulusMX/WS2300Station.cs @@ -108,12 +108,11 @@ private void bw_DoWork(object sender, DoWorkEventArgs e) public override void getAndProcessHistoryData() { int interval; - int countdown; Timestamp ts; int numrecs; cumulus.LogMessage("Reading history info"); - int rec = Ws2300ReadHistoryDetails(out interval, out countdown, out ts, out numrecs); + int rec = Ws2300ReadHistoryDetails(out interval, out _, out ts, out numrecs); if (rec < 0) cumulus.LogMessage("Failed to read history data"); diff --git a/Updates.txt b/Updates.txt index 17b4d947..f41961b0 100644 --- a/Updates.txt +++ b/Updates.txt @@ -1,4 +1,4 @@ -3.10.0 - b3112 +3.10.0 - b3113 —————————————— - Fix: Catch error creating System Uptime counter on Windows - Fix: The Local web server is now brought up before initialising the station. This allows you to correct a misconfigured station without resorting to editing the Cumulus.ini file. From 82089ad458fb1b3aaeb92c6aefc3a2435f41fd34 Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Mon, 22 Feb 2021 15:34:17 +0000 Subject: [PATCH 10/12] b3114 Fix MySQL interset broken in b3008 Adds display options --- CumulusMX/Cumulus.cs | 23 ++++++++++++++--- CumulusMX/Properties/AssemblyInfo.cs | 6 ++--- CumulusMX/StationSettings.cs | 38 +++++++++++++++++++++++++++- CumulusMX/webtags.cs | 21 ++++++++++++++- Updates.txt | 4 ++- 5 files changed, 82 insertions(+), 10 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index eeeda15b..03451589 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -489,6 +489,8 @@ public struct TExtraFiles public SelectaChartOptions SelectaChartOptions = new SelectaChartOptions(); + public DisplayOptions DisplayOptions = new DisplayOptions(); + public bool ListWebTags; public bool RealtimeEnabled; // The timer is to be started @@ -1500,7 +1502,7 @@ internal void SetStartOfRealtimeInsertSQL() { StartOfRealtimeInsertSQL = "INSERT IGNORE INTO " + MySqlRealtimeTable + " (" + "LogDateTime,temp,hum,dew,wspeed,wlatest,bearing,rrate,rfall,press," + - "currentwdir,beaufortnumber,Units.Wind,tempunitnodeg,Units.Press,rainunit," + + "currentwdir,beaufortnumber,windunit,tempunitnodeg,pressunit,rainunit," + "windrun,presstrendval,rmonth,ryear,rfallY,intemp,inhum,wchill,temptrend," + "tempTH,TtempTH,tempTL,TtempTL,windTM,TwindTM,wgustTM,TwgustTM," + "pressTH,TpressTH,pressTL,TpressTL,version,build,wgust,heatindex,humidex," + @@ -1520,12 +1522,12 @@ internal void SetRealtimeSqlCreateString() "bearing VARCHAR(3) NOT NULL," + "rrate decimal(4," + RainDPlaces + ") NOT NULL," + "rfall decimal(4," + RainDPlaces + ") NOT NULL," + - "press decimal(6," + PressDPlaces +") NOT NULL," + + "press decimal(6," + PressDPlaces + ") NOT NULL," + "currentwdir varchar(3) NOT NULL," + "beaufortnumber varchar(2) NOT NULL," + - "Units.Wind varchar(4) NOT NULL," + + "windunit varchar(4) NOT NULL," + "tempunitnodeg varchar(1) NOT NULL," + - "Units.Press varchar(3) NOT NULL," + + "pressunit varchar(3) NOT NULL," + "rainunit varchar(2) NOT NULL," + "windrun decimal(4," + WindRunDPlaces + ") NOT NULL," + "presstrendval varchar(6) NOT NULL," + @@ -4292,6 +4294,9 @@ private void ReadIniFile() NumWindRosePoints = ini.GetValue("Display", "NumWindRosePoints", 16); WindRoseAngle = 360.0 / NumWindRosePoints; + DisplayOptions.UseApparent = ini.GetValue("Display", "UseApparent", false); + DisplayOptions.ShowSolar = ini.GetValue("Display", "DisplaySolarData", false); + DisplayOptions.ShowUV = ini.GetValue("Display", "DisplayUvData", false); // MySQL - common MySqlHost = ini.GetValue("MySQL", "Host", "127.0.0.1"); @@ -4944,6 +4949,9 @@ internal void WriteIniFile() ini.SetValue("Proxies", "HTTPProxyPassword", HTTPProxyPassword); ini.SetValue("Display", "NumWindRosePoints", NumWindRosePoints); + ini.SetValue("Display", "UseApparent", DisplayOptions.UseApparent); + ini.SetValue("Display", "DisplaySolarData", DisplayOptions.ShowSolar); + ini.SetValue("Display", "DisplayUvData", DisplayOptions.ShowUV); ini.SetValue("Graphs", "ChartMaxDays", GraphDays); ini.SetValue("Graphs", "GraphHours", GraphHours); @@ -9633,4 +9641,11 @@ public class WebUploadAprs : WebUploadService { public bool HumidityCutoff; } + + public class DisplayOptions + { + public bool UseApparent { get; set; } + public bool ShowSolar { get; set; } + public bool ShowUV { get; set; } + } } diff --git a/CumulusMX/Properties/AssemblyInfo.cs b/CumulusMX/Properties/AssemblyInfo.cs index 2eacc3c5..0861a2bc 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("Build 3113")] +[assembly: AssemblyDescription("Build 3114")] [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.10.0.3113")] -[assembly: AssemblyFileVersion("3.10.0.3113")] +[assembly: AssemblyVersion("3.10.0.3114")] +[assembly: AssemblyFileVersion("3.10.0.3114")] diff --git a/CumulusMX/StationSettings.cs b/CumulusMX/StationSettings.cs index 51f27ffc..88503de6 100644 --- a/CumulusMX/StationSettings.cs +++ b/CumulusMX/StationSettings.cs @@ -54,6 +54,15 @@ internal string GetStationAlpacaFormData() advanced = optionsAdv }; + // Display Options + var displayOptions = new JsonDisplayOptions() + { + windrosepoints = cumulus.NumWindRosePoints, + useapparent = cumulus.DisplayOptions.UseApparent, + displaysolar = cumulus.DisplayOptions.ShowSolar, + displayuv = cumulus.DisplayOptions.ShowUV + }; + var unitsAdv = new JsonStationSettingsUnitsAdvanced { airqulaitydp = cumulus.AirQualityDPlaces, @@ -365,7 +374,8 @@ internal string GetStationAlpacaFormData() Forecast = forecast, Solar = solar, AnnualRainfall = annualrainfall, - Graphs = graphs + Graphs = graphs, + DisplayOptions = displayOptions }; //return JsonConvert.SerializeObject(data); @@ -604,6 +614,23 @@ internal string UpdateStationConfig(IHttpContext context) context.Response.StatusCode = 500; } + // Display Options + try + { + cumulus.NumWindRosePoints = settings.DisplayOptions.windrosepoints; + cumulus.WindRoseAngle = 360.0 / cumulus.NumWindRosePoints; + cumulus.DisplayOptions.UseApparent = settings.DisplayOptions.useapparent; + cumulus.DisplayOptions.ShowSolar = settings.DisplayOptions.displaysolar; + cumulus.DisplayOptions.ShowUV = settings.DisplayOptions.displayuv; + } + catch (Exception ex) + { + var msg = "Error processing Display Options settings: " + ex.Message; + cumulus.LogMessage(msg); + errorMsg += msg + "\n\n"; + context.Response.StatusCode = 500; + } + // Log rollover try { @@ -1028,6 +1055,7 @@ internal class JsonStationSettingsData public JsonStationSettingsSolar Solar { get; set; } public JsonStationSettingsAnnualRainfall AnnualRainfall { get; set; } public JsonStationSettingsGraphs Graphs { get; set; } + public JsonDisplayOptions DisplayOptions { get; set; } } internal class JsonStationGeneral @@ -1370,4 +1398,12 @@ public class JsonSelectaChartSettings public string[] series { get; set; } public string[] colours { get; set; } } + + public class JsonDisplayOptions + { + public int windrosepoints { get; set; } + public bool useapparent { get; set; } + public bool displaysolar { get; set; } + public bool displayuv { get; set; } + } } diff --git a/CumulusMX/webtags.cs b/CumulusMX/webtags.cs index abdfe3d6..4d151e5e 100644 --- a/CumulusMX/webtags.cs +++ b/CumulusMX/webtags.cs @@ -5007,6 +5007,21 @@ private string TagRcRecentUv(Dictionary tagParams) return ReplaceCommas(TagRecentUv(tagParams)); } + private string TagOption_useApparent(Dictionary tagParams) + { + return cumulus.DisplayOptions.UseApparent ? "1" : "0"; + } + + private string TagOption_showSolar(Dictionary tagParams) + { + return cumulus.DisplayOptions.ShowSolar ? "1" : "0"; + } + + private string TagOption_showUV(Dictionary tagParams) + { + return cumulus.DisplayOptions.ShowUV ? "1" : "0"; + } + public void InitialiseWebtags() { // create the web tag dictionary @@ -5843,7 +5858,11 @@ public void InitialiseWebtags() { "ByMonthLongestDryPeriodT", TagByMonthLongestDryPeriodT }, { "ByMonthLongestWetPeriodT", TagByMonthLongestWetPeriodT }, { "ByMonthLowDailyTempRangeT", TagByMonthLowDailyTempRangeT }, - { "ByMonthHighDailyTempRangeT", TagByMonthHighDailyTempRangeT } + { "ByMonthHighDailyTempRangeT", TagByMonthHighDailyTempRangeT }, + //Options + { "Option_useApparent", TagOption_useApparent }, + { "Option_showSolar", TagOption_showSolar }, + { "Option_showUV", TagOption_showUV } }; cumulus.LogMessage(webTagDictionary.Count + " web tags initialised"); diff --git a/Updates.txt b/Updates.txt index f41961b0..32450bfa 100644 --- a/Updates.txt +++ b/Updates.txt @@ -1,4 +1,4 @@ -3.10.0 - b3113 +3.10.0 - b3114 —————————————— - Fix: Catch error creating System Uptime counter on Windows - Fix: The Local web server is now brought up before initialising the station. This allows you to correct a misconfigured station without resorting to editing the Cumulus.ini file. @@ -11,6 +11,8 @@ - New: The previous Console log file is now copied to an "-old" file on start-up - New: For Davis WLL stations using weatherlink.com, Cumulus now checks and reports the operational status of weatherlink.com on start-up and if an error occurs accessing the service - New: Two web tags <#forumurl> and <#webcamurl>, which just return the respective URLs rather than the pre-canned HTML of <#forum> and <#webcam> +- New: The start of a Display Options section under Station, which controls what data is displayed on the default web site, implementing some of the Cumulus 1 options + - New web tags for this: <#Option_useApparent>, <#Option_showSolar>, <#Option_showUV> - Change: All the settings screens revamped, reorganised and extended. - Many of the settings are now context sensitive, only showing items relevant to your station and configuration. From 35fa803f5afe5fe1feb07ac6b8a77e4250327efa Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Wed, 24 Feb 2021 12:20:39 +0000 Subject: [PATCH 11/12] b3115 Shutdown improvements when running as a Linux service --- CumulusMX/Cumulus.cs | 2 ++ CumulusMX/DavisStation.cs | 4 ++-- CumulusMX/Program.cs | 24 +++++++++++++++++++++--- CumulusMX/Properties/AssemblyInfo.cs | 6 +++--- Updates.txt | 4 +++- 5 files changed, 31 insertions(+), 9 deletions(-) diff --git a/CumulusMX/Cumulus.cs b/CumulusMX/Cumulus.cs index 03451589..7eeef3cd 100644 --- a/CumulusMX/Cumulus.cs +++ b/CumulusMX/Cumulus.cs @@ -1043,6 +1043,8 @@ public Cumulus(int HTTPport, bool DebugEnabled, string startParms) { // no response wait 10 seconds before trying again Thread.Sleep(10000); + // Force a DNS refresh + Dns.GetHostEntry(ProgramOptions.StartupPingHost); } } while ((reply == null || reply.Status != IPStatus.Success) && DateTime.Now < endTime); diff --git a/CumulusMX/DavisStation.cs b/CumulusMX/DavisStation.cs index 6937327e..3613b145 100644 --- a/CumulusMX/DavisStation.cs +++ b/CumulusMX/DavisStation.cs @@ -1593,12 +1593,12 @@ private void GetAndProcessLoopData(int number) StormRain = ConvertRainClicksToUser(loopData.StormRain); StartOfStorm = loopData.StormRainStart; - if (loopData.UVIndex >= 0 && loopData.UVIndex < 25) + if (loopData.UVIndex >= 0 && loopData.UVIndex < 17) { DoUV(loopData.UVIndex, now); } - if (loopData.SolarRad >= 0 && loopData.SolarRad < 5000) + if (loopData.SolarRad >= 0 && loopData.SolarRad < 1801) { DoSolarRad(loopData.SolarRad, now); } diff --git a/CumulusMX/Program.cs b/CumulusMX/Program.cs index 9b0c38ff..272d632c 100644 --- a/CumulusMX/Program.cs +++ b/CumulusMX/Program.cs @@ -69,9 +69,23 @@ private static void Main(string[] args) // Wait for a signal to be delivered unixSignalWaitAny?.Invoke(null, new object[] {signals}); + var msg = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff ") + "Exiting system due to external SIGTERM signal"; + Console.WriteLine(msg); + svcTextListener.WriteLine(msg); + if (cumulus != null) { - cumulus.LogConsoleMessage("\nExiting system due to external SIGTERM signal"); + msg = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff ") + "Cumulus terminating"; + Console.WriteLine(msg); + svcTextListener.WriteLine(msg); + cumulus.LogMessage("Exiting system due to external SIGTERM signal"); + cumulus.LogMessage("Cumulus terminating"); + cumulus.Stop(); + //allow main to run off + Thread.Sleep(500); + msg = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff ") + "Cumulus has shutdown"; + Console.WriteLine(msg); + svcTextListener.WriteLine(msg); } exitSystem = true; @@ -88,6 +102,8 @@ private static void Main(string[] args) cumulus.LogConsoleMessage("Ctrl+C pressed"); cumulus.LogConsoleMessage("\nCumulus terminating"); cumulus.Stop(); + //allow main to run off + Thread.Sleep(500); } Trace.WriteLine("Cumulus has shutdown"); ev.Cancel = true; @@ -283,6 +299,8 @@ private static void UnhandledExceptionTrapper(object sender, UnhandledExceptionE } } + + // Windows ExitHandler public class ExitHandler { [DllImport("Kernel32")] @@ -319,6 +337,8 @@ private static bool Handler(CtrlType sig) { Program.cumulus.LogConsoleMessage("Cumulus terminating"); Program.cumulus.Stop(); + //allow main to run off + Thread.Sleep(500); } else { @@ -329,8 +349,6 @@ private static bool Handler(CtrlType sig) Trace.WriteLine("Cumulus has shutdown"); Console.WriteLine("Cumulus stopped"); - //allow main to run off - Thread.Sleep(200); Program.exitSystem = true; return true; diff --git a/CumulusMX/Properties/AssemblyInfo.cs b/CumulusMX/Properties/AssemblyInfo.cs index 0861a2bc..87e0a2ad 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("Build 3114")] +[assembly: AssemblyDescription("Build 3115")] [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.10.0.3114")] -[assembly: AssemblyFileVersion("3.10.0.3114")] +[assembly: AssemblyVersion("3.10.0.3115")] +[assembly: AssemblyFileVersion("3.10.0.3115")] diff --git a/Updates.txt b/Updates.txt index 32450bfa..6c80da38 100644 --- a/Updates.txt +++ b/Updates.txt @@ -1,10 +1,12 @@ -3.10.0 - b3114 +3.10.0 - b3115 —————————————— - Fix: Catch error creating System Uptime counter on Windows - Fix: The Local web server is now brought up before initialising the station. This allows you to correct a misconfigured station without resorting to editing the Cumulus.ini file. - Fix: Diary Editor creating entries on the wrong day, and revamp the interface a bit - Fix: WLL day average temp stats on historic catch-up - Fix: GW1000 auto-discovery was triggering an erroneous IP address change +- Fix: Cumulus MX shutdown when running as a system service is now orderly +- Fix: The start-up ping now refreshes the DNS cache before every re-try to avoid using null entries cached before the internet comes up - New: Brand new default web site template courtesy of Neil Thomas. The original "legacy" web site is still included, but it has been moved to the /webfiles-legacy folder. - The new web site is now data file driven as opposed to all pages being processed and uploaded. The legacy web site has also been updated to use this method. From 53c6da45044c26bc18e1d438efe227e1663085c3 Mon Sep 17 00:00:00 2001 From: Mark Crossley <1196094+mcrossley@users.noreply.github.com> Date: Wed, 24 Feb 2021 15:58:05 +0000 Subject: [PATCH 12/12] Tighten Davis Loop pressure range checks --- CumulusMX/DavisStation.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/CumulusMX/DavisStation.cs b/CumulusMX/DavisStation.cs index 3613b145..a428af8f 100644 --- a/CumulusMX/DavisStation.cs +++ b/CumulusMX/DavisStation.cs @@ -1515,6 +1515,10 @@ private void GetAndProcessLoopData(int number) { DoOutdoorHumidity(loopData.OutsideHumidity, now); } + else + { + cumulus.LogDebugMessage($"LOOP: Ignoring outdoor humidity data. RH={loopData.OutsideHumidity} %."); + } if ((loopData.InsideTemperature > -200) && (loopData.InsideTemperature < 300)) { @@ -1525,11 +1529,20 @@ private void GetAndProcessLoopData(int number) { DoOutdoorTemp(ConvertTempFToUser(loopData.OutsideTemperature), now); } + else + { + cumulus.LogDebugMessage($"LOOP: Ignoring outdoor temp data. Temp={loopData.OutsideTemperature} F."); + } - if ((loopData.Pressure > 0) && (loopData.Pressure < 40)) + if ((loopData.Pressure >= 20) && (loopData.Pressure < 32.5)) { DoPressure(ConvertPressINHGToUser(loopData.Pressure), now); } + else + { + cumulus.LogDebugMessage($"LOOP: Ignoring pressure data. Pressure={loopData.Pressure} inHg."); + } + DoPressTrend("Pressure trend");