Exemple #1
0
        /// <summary>
        /// Requests that the <see cref="SensingAgent"/> consider beginning sensing control.
        /// </summary>
        /// <returns>A <see cref="ControlCompletionCheck"/> to be configured upon return, or <c>null</c> for no such check.</returns>
        /// <param name="cancellationToken">Cancellation token.</param>
        public async Task <ControlCompletionCheck> ActAsync(CancellationToken cancellationToken)
        {
            try
            {
                ControlCompletionCheck controlCompletionCheck = null;

                if (await TransitionToNewStateAsync(SensingAgentState.ActiveObservation, true, cancellationToken))
                {
                    // observe data for the specified duration. the current method is run as a scheduled callback, so we're guaranteed
                    // to have some amount of background time. but watch out for background time expiration on iOS by monitoring the
                    // passed cancellation token. an exception will be thrown if it expires, and it will be caught to return the agent
                    // to idle.
                    SensusServiceHelper.Logger.Log("Sensing agent " + Id + " is actively observing data for " + ActiveObservationDuration.Value + ".", LoggingLevel.Normal, GetType());
                    await Task.Delay(ActiveObservationDuration.Value, cancellationToken);

                    // check criterion and begin control if warranted
                    if (ObservedDataMeetControlCriterion())
                    {
                        controlCompletionCheck = await BeginControlAsync(SensingAgentState.ActiveControl, cancellationToken);
                    }
                    else
                    {
                        await TransitionToNewStateAsync(SensingAgentState.Idle, true, cancellationToken);
                    }
                }

                return(controlCompletionCheck);
            }
            catch (Exception ex)
            {
                await ReturnToIdle(cancellationToken);

                throw ex;
            }
        }
Exemple #2
0
        private async Task <ControlCompletionCheck> BeginControlAsync(SensingAgentState controlState, CancellationToken cancellationToken)
        {
            // this is a convenience method for beginning both active and opportunistic control. control state must be one of these two.
            if (controlState != SensingAgentState.ActiveControl && controlState != SensingAgentState.OpportunisticControl)
            {
                throw new Exception("Unrecognized control state:  " + controlState);
            }

            ControlCompletionCheck controlCompletionCheck = null;

            if (await TransitionToNewStateAsync(controlState, true, cancellationToken))
            {
                controlCompletionCheck = new ControlCompletionCheck(async controlCompletionCheckCancellationToken =>
                {
                    // the current check is called when a protocol is shutting down, and periodically while the
                    // protocol remains running. as long as the protocol is running and the observed data meet
                    // the control criterion, continue with sensing control; otherwise, end control and return
                    // to idle.
                    if (Protocol.State == ProtocolState.Running && ObservedDataMeetControlCriterion())
                    {
                        SensusServiceHelper.Logger.Log("Continuing sensing control in state:  " + StateDescription, LoggingLevel.Normal, GetType());
                    }
                    else
                    {
                        await ReturnToIdle(controlCompletionCheckCancellationToken);
                    }

                    return(State);
                }, ControlCompletionCheckInterval, "Sensus would like to measure your environment. Please open this notification.", "Measuring environment. You may close this alert.");

                SensusServiceHelper.Logger.Log("Established sensing control in state:  " + StateDescription, LoggingLevel.Normal, GetType());
            }

            return(controlCompletionCheck);
        }
Exemple #3
0
        /// <summary>
        /// Asks the agent to observe an <see cref="IDatum"/> object that was generated by Sensus, either during
        /// <see cref="SensingAgentState.OpportunisticObservation"/> or during <see cref="SensingAgentState.ActiveObservation"/>.
        /// </summary>
        /// <returns>A <see cref="ControlCompletionCheck"/> to be configured upon return, or <c>null</c> for no such check.</returns>
        /// <param name="datum">Datum.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        public async Task <ControlCompletionCheck> ObserveAsync(IDatum datum, CancellationToken cancellationToken)
        {
            // certain probes (e.g., ios activity polling) return a null datum to signal that polling occurred
            // but no data were returned. ignore any such null readings when observing.
            if (datum == null)
            {
                return(null);
            }

            // accumulate observed data by type for later analysis
            lock (_typeData)
            {
                Type datumType = datum.GetType();

                if (!_typeData.TryGetValue(datumType, out List <IDatum> data))
                {
                    data = new List <IDatum>();
                    _typeData.Add(datumType, data);
                }

                data.Add(datum);

                UpdateObservedData(_typeData);
            }

            // run opportunistic observation and control if warranted
            ControlCompletionCheck opportunisticControlCompletionCheck = null;

            try
            {
                // the current method is called at high rates during normal operation (e.g., when observing the
                // accelerometer). we want to avoid flooding the local data store with an agent-state datum for
                // each call, so don't write them here.
                if (await TransitionToNewStateAsync(SensingAgentState.OpportunisticObservation, false, cancellationToken))
                {
                    if (ObservedDataMeetControlCriterion())
                    {
                        opportunisticControlCompletionCheck = await BeginControlAsync(SensingAgentState.OpportunisticControl, cancellationToken);
                    }
                    else
                    {
                        await TransitionToNewStateAsync(SensingAgentState.Idle, false, cancellationToken);
                    }
                }
            }
            catch (Exception ex)
            {
                await ReturnToIdle(cancellationToken);

                throw ex;
            }

            return(opportunisticControlCompletionCheck);
        }