private async void OnVisibilityChanged(object sender, VisibilityChangedEventArgs e) { Toast.Debug("OnVisibilityChanged", ""); // _rootFrame will only ever be null here once. // If there is no content the app was prelaunched and we must navigate and begin the session. if (RootFrame.Content == null) { // Page navigation is somthing we do immediately after prelaunch is over. // Any suspend before this point could be assumed to be a part of prelaunch and be ignored. _notPrelaunchSuspend = true; Type pageType; var settings = Settings.Instance; if (settings.IsLoggedIn) { pageType = typeof(SyncingView); } else { pageType = typeof(LandingPage); } RootFrame.Navigate(pageType); Window.Current.Activate(); if (_extendedExecutionSession == null) { await StartExtendedSession(); } } }
/// <summary>Lifecycle suspend.</summary> /// <param name="sender">The source of the suspend request.</param> /// <param name="e">Details about the suspend request.</param> private async void OnSuspending(object sender, SuspendingEventArgs e) { Toast.Debug("OnSuspending", e.SuspendingOperation.ToString()); // This is the most accurate thing that we can tell the user. // There is no way to know if the app is being terminated or just suspended for fun. if (_notPrelaunchSuspend) { Toast.NotifyUserOfInformation("App is suspending."); } else { Toast.Debug("OnSuspending", "Prelaunch"); } // If the deferral is not obtained the suspension proceeds at the end of this method. // With the deferral there is still a 5 second time limit to completing suspension code. // The deferral allows code to be awaited in this method. var deferral = e.SuspendingOperation.GetDeferral(); var completer = new TaskCompletionSource <object>(); AddSessionTask(completer.Task); await Messenger.Instance.Suspending.Invoke(completer, true, true); await completer.Task; _networking?.Suspend(); WebSocketConnection.Instance.Suspend(); deferral.Complete(); }
/// <summary>Fired when the user attempts to open the program, even whent he program is already open. /// This gets fired when the user clicks notifications, resulting in this being called in an already /// running application.</summary> /// <param name="e">Details about the launch request and process.</param> protected override async void OnLaunched(LaunchActivatedEventArgs e) { // Only initialise if the program is not already open. if (RootFrame == null) { // Creates a frame and shoves it in the provided default window. RootFrame = new Frame(); RootFrame.NavigationFailed += OnNavigationFailed; Window.Current.Content = RootFrame; Window.Current.VisibilityChanged += OnVisibilityChanged; Dispatcher = Window.Current.Dispatcher; } // If the user launches the app when it is already open, just bring it to foreground. Window.Current.Activate(); if (e.PrelaunchActivated) { // We must not try starting an extended session in this situation. Toast.Debug("OnLaunched", "Prelaunched"); } else { // There could be a session open if the app is launched twice. if (_extendedExecutionSession == null) { await StartExtendedSession(); } } }
/// <summary>This only gets called if the application is activated via some special means. We are not /// currently doing so.</summary> /// <param name="args"></param> protected override void OnActivated(IActivatedEventArgs args) { switch (args.PreviousExecutionState) { case ApplicationExecutionState.ClosedByUser: case ApplicationExecutionState.NotRunning: Toast.Debug("OnActivated", "NotRunning or ClosedByUser"); break; case ApplicationExecutionState.Running: Toast.Debug("OnActivated", "Running"); break; case ApplicationExecutionState.Suspended: Toast.Debug("OnActivated", "Suspended"); break; case ApplicationExecutionState.Terminated: Toast.Debug("OnActivated", "Terminated"); break; default: throw new ArgumentOutOfRangeException(); } }
private async void OnResuming(object sender, object e) { Toast.Debug("OnResuming", ""); var completer = new TaskCompletionSource <object>(); AddSessionTask(completer.Task); await Messenger.Instance.Resuming.Invoke(completer, true, true); await completer.Task; _networking?.Resume(); WebSocketConnection.Instance.Resume(); }
/// <summary>Starts a new session, assuming the old one has been closed. I hope you did a null check.</summary> /// <returns>awaitable</returns> private async Task StartExtendedSession() { _extendedExecutionSession = new ExtendedExecutionSession { Reason = ExtendedExecutionReason.Unspecified, Description = "Live data needs to be synchronised to allow important alerts." }; _extendedExecutionSession.Revoked += ExtendedExecutionRevoked; var result = await _extendedExecutionSession.RequestExtensionAsync(); if (result == ExtendedExecutionResult.Allowed) { Toast.Debug("EES", "Success"); } else { // The request has failed, kill will null it, and then the app will try again when the visibility changes. KillExtendedExecutionSession(); Toast.NotifyUserOfError("Windows error, program may fail to record, sync and alert when minimised."); } }
/// <summary>Errors that should never happen but are silently ignored none-the-less.</summary> /// <param name="wat">Some descritpion that ay help debug the problem.</param> public static void ShouldNeverHappen(string wat) { Toast.Debug("SHOULD NEVER HAPPEN", wat); }
//Closes sensor Histories that are no longer usefull private void SaveBufferedReadings(object sender, object e) { Toast.Debug("SaveBufferedReadings", $"{DateTimeOffset.Now.DateTime} Datapointsaver"); _localTask = _localTask.ContinueWith(previous => { //if (Settings.Instance.LastSuccessfulGeneralDbGet > DateTimeOffset.Now - TimeSpan.FromMinutes(5)) //{ Debug.WriteLine("Datasaver started, did not bother detecting a recent update."); using (var db = new MainDbContext()) { for (var i = 0; i < _sensorBuffer.Count; i++) { var sbuffer = _sensorBuffer[i]; SensorDatapoint sensorDatapoint = null; if (sbuffer.FreshBuffer.Count > 0) { var startTime = sbuffer.FreshBuffer[0].TimeStamp; var endTime = sbuffer.FreshBuffer.Last().TimeStamp; var duration = (endTime - startTime).Subtract(sbuffer.FreshBuffer[0].Duration); var cumulativeDuration = TimeSpan.Zero; double cumulativeValue = 0; for (var b = 0; b < sbuffer.FreshBuffer.Count; b++) { cumulativeDuration += sbuffer.FreshBuffer[b].Duration; cumulativeValue += sbuffer.FreshBuffer[b].Value; } var sensorType = _sensorTypes.First(st => st.ID == sbuffer.Sensor.SensorTypeID); var value = cumulativeValue / sbuffer.FreshBuffer.Count; if (sensorType.ParamID == 5) // Level { sensorDatapoint = new SensorDatapoint(Math.Round(value), endTime, duration); } else if (sensorType.ParamID == 9) //water flow { sensorDatapoint = new SensorDatapoint(value, endTime, cumulativeDuration); } else { sensorDatapoint = new SensorDatapoint(value, endTime, duration); } sbuffer.FreshBuffer.RemoveRange(0, sbuffer.FreshBuffer.Count); } //only if new data is present if (sensorDatapoint != null) { //check if corresponding dataDay is too old or none exists at all if (sbuffer.DataDay?.TimeStamp < sensorDatapoint.TimeStamp || sbuffer.DataDay == null) { var dataDay = new SensorHistory { LocationID = sbuffer.Sensor.Device.LocationID, SensorID = sbuffer.Sensor.ID, Sensor = sbuffer.Sensor, TimeStamp = Tomorrow, Data = new List <SensorDatapoint>() }; _sensorBuffer[i] = new SensorBuffer(sbuffer.Sensor, dataDay); //Only uses this entity, and does not follow the references to stick related references in the DB db.Entry(dataDay).State = EntityState.Added; } else { //this will not attach related entities, which is good db.Entry(sbuffer.DataDay).State = EntityState.Unchanged; } _sensorBuffer[i].DataDay.Data.Add(sensorDatapoint); _sensorBuffer[i].DataDay.SerialiseData(); } } //for loop ends //Once we are done here, mark changes to the db db.SaveChanges(); Debug.WriteLine("Saved Sensor Data"); } //} //else //{ // Debug.WriteLine("Skipped datasaver due to lack of recent update."); //} }); }