public void LoadData(bool forceRefresh) { if (IsLoading) { return; } // Don't download new data if current is less than a minute old if (!forceRefresh) { if (LastUpdated != DateTime.MinValue) { TimeSpan difference = DateTime.UtcNow - LastUpdated; if (difference.TotalMinutes < 1) { return; } } } new Thread(delegate() { Application.Current.Dispatcher.Invoke(delegate { DataDownloadStarted?.Invoke(this, new EventArgs()); }); bool reportError = false; bool graphError = false; DateTime dataTime = DateTime.UtcNow; string utc = dataTime.ToString("yyyy-MM-dd'T'HH-mm-00"); // Download and deserialise report for current time try { string reportUrl = Path.Combine(Properties.Settings.Default .DataEndpoint + "/", "data/reports.php?time=" + utc); string reportData = RequestURL(reportUrl); if (reportData == "1") { throw new Exception("Server-side error"); } Report reportJson = JsonConvert.DeserializeObject <Report>(reportData); // Recalibrate time to returned record time dataTime = DateTime.Parse(reportJson.Time); dataTime = DateTime.SpecifyKind(dataTime, DateTimeKind.Utc); utc = dataTime.ToString("yyyy-MM-dd'T'HH-mm-ss"); Application.Current.Dispatcher.Invoke(delegate { if (reportJson.AirT != null) { LabelAirT.Content = ((double)reportJson.AirT).ToString("0.0") + "°C"; } else { LabelAirT.Content = "No Data"; } if (reportJson.RelH != null) { LabelRelH.Content = ((double)reportJson.RelH).ToString("0.0") + "%"; } else { LabelRelH.Content = "No Data"; } if (reportJson.DewP != null) { LabelDewP.Content = ((double)reportJson.DewP).ToString("0.0") + "°C"; } else { LabelDewP.Content = "No Data"; } if (reportJson.WSpd != null) { LabelWSpd.Content = ((double)reportJson.WSpd).ToString("0.0") + " mph"; } else { LabelWSpd.Content = "No Data"; } if (reportJson.WDir != null) { LabelWDir.Content = reportJson.WDir.ToString() + "° (" + DegreesToCompass((int)reportJson.WDir) + ")"; } else { LabelWDir.Content = "No Data"; } if (reportJson.WGst != null) { LabelWGst.Content = ((double)reportJson.WGst).ToString("0.0") + " mph"; } else { LabelWGst.Content = "No Data"; } if (reportJson.SunD_PHr != null) { TimeSpan ts = TimeSpan.FromSeconds((double)reportJson.SunD_PHr); LabelSunDPHr.Content = new DateTime(ts.Ticks).ToString("HH:mm:ss"); } else { LabelSunDPHr.Content = "No Data"; } if (reportJson.Rain_PHr != null) { LabelRainPHr.Content = ((double)reportJson.Rain_PHr).ToString("0.00") + " mm"; } else { LabelRainPHr.Content = "No Data"; } if (reportJson.MSLP != null) { LabelMSLP.Content = ((double)reportJson.MSLP).ToString("0.0") + " hPa"; } else { LabelMSLP.Content = "No Data"; } if (reportJson.StaP_PTH != null) { LabelStaPPTH.Content = ((double)reportJson.StaP_PTH).ToString("+0.0;-0.0") + " hPa"; } else { LabelStaPPTH.Content = "No Data"; } if (reportJson.ST10 != null) { LabelST10.Content = ((double)reportJson.ST10).ToString("0.0") + "°C"; } else { LabelST10.Content = "No Data"; } if (reportJson.ST30 != null) { LabelST30.Content = ((double)reportJson.ST30).ToString("0.0") + "°C"; } else { LabelST30.Content = "No Data"; } if (reportJson.ST00 != null) { LabelST00.Content = ((double)reportJson.ST00).ToString("0.0") + "°C"; } else { LabelST00.Content = "No Data"; } }); } catch { reportError = true; Application.Current.Dispatcher.Invoke(delegate { LabelAirT.Content = "No Data"; LabelRelH.Content = "No Data"; LabelDewP.Content = "No Data"; LabelWSpd.Content = "No Data"; LabelWDir.Content = "No Data"; LabelWGst.Content = "No Data"; LabelSunDPHr.Content = "No Data"; LabelRainPHr.Content = "No Data"; LabelMSLP.Content = "No Data"; LabelStaPPTH.Content = "No Data"; LabelST10.Content = "No Data"; LabelST30.Content = "No Data"; LabelST00.Content = "No Data"; }); } // Download and deserialise chart data for current day try { string graphUrl = Path.Combine(Properties.Settings.Default.DataEndpoint + "/", "data/graph-day.php?time=" + utc + "&fields=AirT"); string graphData = RequestURL(graphUrl); if (graphData == "1") { throw new Exception("Server-side error"); } graphData = graphData.Replace("[[", "[").Replace("]]", "]"); List <ChartPoint> graphJson = JsonConvert.DeserializeObject <List < ChartPoint> >(graphData); Application.Current.Dispatcher.Invoke(delegate { ChartModel.ClearPoints(); foreach (var item in graphJson) { if (item.Y != null) { ChartModel.AddPoint(UTCToLocal(item.X), (double)item.Y); } } // Calculate chart boundaries var bounds = GetDayBounds(UTCToLocal(dataTime)); DateTimeAxisAirTX.Minimum = DateTimeAxis.ToDouble(bounds.Item1); DateTimeAxisAirTX.Maximum = DateTimeAxis.ToDouble(bounds.Item2); SetYAxisSettings(); PlotAirT.InvalidatePlot(); }); } catch { graphError = true; Application.Current.Dispatcher.Invoke(delegate { ChartModel.ClearPoints(); }); } // If any request succeeded, set the loaded time if (!reportError || !graphError) { LastUpdated = dataTime; DataTime = dataTime; } Application.Current.Dispatcher.Invoke(delegate { DataDownloadCompleted?.Invoke(this, new EventArgs()); }); }).Start(); }