Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manually triggering an event-based measure once #286

Open
koenniem opened this issue Nov 24, 2022 · 3 comments
Open

Manually triggering an event-based measure once #286

koenniem opened this issue Nov 24, 2022 · 3 comments
Assignees
Labels
enhancement New feature or request question Further information is requested

Comments

@koenniem
Copy link

CARP now resumes sampling when the app restarts as part of the brand new release 0.40.0. This is a great (and much needed) feature as operating systems become more aggressive in killing apps that consume power in the background.

However, there is one component missing to bridge the gap of missing data: triggering event-based measures only once. For example, instead of waiting for a change in screen state to come in after the app has been killed and restarted, it would be useful to know what the current screen state is. In the case of screen states, I suppose one could infer this because each screen off event must be followed by a screen on event, but this is not the case for all sensors. Thus, manually requesting the current state of event-based sensors - rather than resuming sampling and waiting for a new event - may be advantageous for minimising data gaps.

Now, I am not sure how feasible this is for all sensors, as the underlying API in some cases is truly event-based, but I believe it is feasible in most cases. Activity recognition and screen state are of particular interest because, unlike other event-based sensors, these do not immediately sample when resumed. For the other event-based sensors, a workaround would be to create a very brief periodic measurement so that they are only triggered once, but I believe a more appropriate solution would be preferable.

@sc00n
Copy link
Contributor

sc00n commented Dec 2, 2022

I found out that (at least for pedometer) it works to also add an intervaltrigger:

      protocol.addTriggeredTask(
          IntervalTrigger(period: Duration(seconds: 5)),
          BackgroundTask()
            ..addMeasure(Measure(type: SensorSamplingPackage.PEDOMETER)),
          phone);

      protocol.addTriggeredTask(
          ImmediateTrigger(),
          BackgroundTask()
            ..addMeasure(Measure(type: SensorSamplingPackage.PEDOMETER)),
          phone);

In this case (on Android), It recorded the steps every 5 seconds AND with every step. I don't know if there is anything against using an interval trigger for event based measures?

This seems to work for

  • Pedometer
  • Battery

But not for

  • Activity
  • Screen

@bardram bardram self-assigned this Dec 6, 2022
@bardram bardram added enhancement New feature or request question Further information is requested labels Dec 6, 2022
@bardram
Copy link
Contributor

bardram commented Dec 6, 2022

I'm not quite sure what you're asking for here.

If you want to listen to screen events you would write something like:

  controller?.data
      .where((dataPoint) =>
          dataPoint.data!.format.toString() == DeviceSamplingPackage.SCREEN)
      .listen((event) => print(event));

But of course this would only work if the app is running (in the background also).

Is what you're asking for some sort of "state" for each probe / measure, so you can get the lastes read data point before the app was killed?

@koenniem
Copy link
Author

koenniem commented Dec 6, 2022

Is what you're asking for some sort of "state" for each probe / measure, so you can get the lastes read data point before the app was killed?

Not quite. The problem with the screen sensor (and with other event-based sensors) is that it only registers changes, which means the state of the screen is unknown when the app restarts until a new change comes in. Let me clarify the problem with the example:

Suppose we want to measure the time the screen is unlocked. We have the following sequence:

time screen_event
10:00:00 SCREEN_OFF
10:05:00 SCREEN_UNLOCKED
10:10:00 GAP
10:15:00 END GAP
10:20:00 SCREEN_OFF

Somehow we know the app was killed at 10:10:00 and restarted at 10:15:00.

  • From 10:00:00 to 10:05:00, the screen was off.
  • From 10:05:00 to 10:10:00, the screen was unlocked.
  • Once the gap occurred at 10:00:00, we might start to miss screen changes. We might "impute" the screen was unlocked the entire gap, but it's equally likely that one or multiple screen events occurred.
  • From 10:15:00 to 10:20:00, we are able to register screen changes but none occur until 10:20:00, when the screen is turned off.

The total time the screen was unlocked is then 5 minutes, plus another 5 if we suppose no changes occurred in the gap, and then another 5 minutes if we made this assumption as no other changes were registered.

The problem in this example is from 10:15:00 to 10:20:00. The app was running, yet we do not know what the screen state was. If we could query the "current" screen state on-demand instead of waiting for a change, we could recover some valuable data.

In this example the time between measurements is quite short, but it's easy to see these assumptions become much more risky when the time between measurements is hours rather than minutes. Thus, if we could query the current states of these events (current screen state, current activity, etc.), we could minimise the amount of data lost because of these gaps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants