public void SetValue(string fieldName, string newValue, ref bool changed) { if (!Props.TryGetValue(fieldName, out string existingValue) || newValue != existingValue) { Props[fieldName] = newValue; if (fieldName == "time") { ProcessNewTime(Updated); } else if (fieldName == "wind_dir_deg" && double.TryParse(newValue, out double windDirDeg)) { CompassDirection dir = Compass.GetCompassDirection((int)Math.Round(windDirDeg)); Props["wind_dir_abbr"] = dir.ToString(); Props["wind_dir_full"] = Compass.GetCompassDirectionName(dir); } else if (fieldName == "humidity" || fieldName == "temperature_C" || fieldName == "temperature_F") { if (fieldName == "temperature_C") { Props["temperature_F"] = Convert_C_to_F(newValue); } else if (fieldName == "temperature_F") { Props["temperature_C"] = Convert_F_to_C(newValue); } if (Props.TryGetValue("humidity", out string strHumidity) && double.TryParse(strHumidity, out double humidity) && Props.TryGetValue("temperature_C", out string strC) && double.TryParse(strC, out double C)) { double absoluteHumidityGramsPerCubicMeter = (6.112 * Math.Pow(Math.E, (17.67 * C) / (C + 243.5)) * (humidity * 2.1674)) / (273.15 + C); Props["humdity_abs_gpm3"] = absoluteHumidityGramsPerCubicMeter.ToString("0.#"); } } changed = true; } }
/// <summary> /// Process an updated timestamp. This does things like parse the time string and update wind low and high values. /// </summary> /// <param name="newTimeStr"></param> private void ProcessNewTime(DateTime?updated) { if (updated == null) { Props["time_epoch_ms"] = "0"; Props["time_local"] = ""; return; } Props["time_epoch_ms"] = TimeUtil.GetTimeInMsSinceEpoch(updated.Value).ToString(); Props["time_local"] = updated.Value.ToString("yyyy-MM-dd hh:mm:ss tt"); SetTimeout.OnBackground(() => { try { updated = Updated; bool hasAnyWindData = false; // Compute wind averages over time double wind_dir_deg = 0; if (!Props.TryGetValue("wind_dir_deg", out string str_wind_dir_deg) || !double.TryParse(str_wind_dir_deg, out wind_dir_deg)) { wind_dir_deg = 0; } if (Props.TryGetValue("wind_avg_mi_h", out string str_wind_speed_mph) && double.TryParse(str_wind_speed_mph, out double wind_speed_mph)) { hasAnyWindData = true; windTrackerMi.Add(wind_speed_mph, wind_dir_deg); RollingMinMaxAvg.StoredValue low = windTrackerMi.GetMinimum(); CompassDirection dir = Compass.GetCompassDirection((int)Math.Round(low.directionDegrees)); Props["wind_5min_low_mi_h"] = low.speed.ToString(); Props["wind_5min_low_mi_dir_abbr"] = dir.ToString(); Props["wind_5min_low_mi_dir_full"] = Compass.GetCompassDirectionName(dir); RollingMinMaxAvg.StoredValue high = windTrackerMi.GetMaximum(); dir = Compass.GetCompassDirection((int)Math.Round(high.directionDegrees)); Props["wind_5min_high_mi_h"] = high.speed.ToString(); Props["wind_5min_high_mi_dir_abbr"] = dir.ToString(); Props["wind_5min_high_mi_dir_full"] = Compass.GetCompassDirectionName(dir); RollingMinMaxAvg.StoredValue avg = windTrackerMi.GetAverage(); dir = Compass.GetCompassDirection((int)Math.Round(avg.directionDegrees)); Props["wind_5min_avg_mi_h"] = avg.speed.ToString(); Props["wind_5min_avg_mi_dir_abbr"] = dir.ToString(); Props["wind_5min_avg_mi_dir_full"] = Compass.GetCompassDirectionName(dir); } if (Props.TryGetValue("wind_avg_km_h", out string str_wind_speed_kph) && double.TryParse(str_wind_speed_kph, out double wind_speed_kph)) { windTrackerKm.Add(wind_speed_kph, wind_dir_deg); RollingMinMaxAvg.StoredValue low = windTrackerKm.GetMinimum(); CompassDirection dir = Compass.GetCompassDirection((int)Math.Round(low.directionDegrees)); Props["wind_5min_low_km_h"] = low.speed.ToString(); Props["wind_5min_low_km_dir_abbr"] = dir.ToString(); Props["wind_5min_low_km_dir_full"] = Compass.GetCompassDirectionName(dir); RollingMinMaxAvg.StoredValue high = windTrackerKm.GetMaximum(); dir = Compass.GetCompassDirection((int)Math.Round(high.directionDegrees)); Props["wind_5min_high_km_h"] = high.speed.ToString(); Props["wind_5min_high_km_dir_abbr"] = dir.ToString(); Props["wind_5min_high_km_dir_full"] = Compass.GetCompassDirectionName(dir); RollingMinMaxAvg.StoredValue avg = windTrackerKm.GetAverage(); dir = Compass.GetCompassDirection((int)Math.Round(avg.directionDegrees)); Props["wind_5min_avg_km_h"] = avg.speed.ToString(); Props["wind_5min_avg_km_dir_abbr"] = dir.ToString(); Props["wind_5min_avg_km_dir_full"] = Compass.GetCompassDirectionName(dir); } if (hasAnyWindData) { int speed = (int)Math.Round(WindSpeedMph); int gust = (int)Math.Round(WindGustMph); StringBuilder sbWind = new StringBuilder(); if (speed == 0 && gust == 0) { sbWind.Append("Calm"); } else { if (speed > 0) { sbWind.Append(speed + " MPH " + WindDirAbbr); if (gust > speed) { sbWind.Append(", "); } } if (gust > speed) { sbWind.Append("gusting to " + gust); if (speed == 0) { sbWind.Append(" MPH " + WindGustDirAbbr); } } } Props["wind_desc_mi"] = sbWind.ToString(); } } catch (Exception ex) { try { OnBackgroundError(this, ex); } catch (Exception ex2) { Logger.Debug(ex2, "MqttDevice OnBackgroundError event"); } } try { OnUpdate(this, new EventArgs()); } catch (Exception ex) { Logger.Debug(ex, "MqttDevice OnUpdate event"); } }, 250); }