Beispiel #1
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);
        }