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

Estimate and display contact durations on exposure match #158

Open
scottleibrand opened this issue Apr 27, 2020 · 8 comments
Open

Estimate and display contact durations on exposure match #158

scottleibrand opened this issue Apr 27, 2020 · 8 comments
Milestone

Comments

@scottleibrand
Copy link
Contributor

If more than one TCN matches from a given TCK, we should estimate and display the duration of the contact.

@scottleibrand scottleibrand added this to the 0.4 milestone Apr 28, 2020
@ivnsch
Copy link
Collaborator

ivnsch commented Jul 9, 2020

This doesn't seem possible on iOS.

The TCNs are generated only when receiving a read request, and the request is sent only of the central hasn't a cached TCN for the device's UUID yet. This UUIDs seems (it's not documented) to be assigned for long periods of time (permanently?). The relationship to the MAC rotation is unclear. I'm observing the UUIDs of 2 iOS peripherals right now and they haven't changed in more than one hour.

A possible solution is to store the duration for individual TCNs and aggregate them during matching (checking that they're contiguous).

An easier one would be to implement a timer to invalidate the cache, in order to fetch/trigger the TCN generation on the peripheral, but this seems questionable with multiple centrals, as they'd make the peripheral change its TCN very frequently and this would break e.g. the distance tracking (unless we base it on the device UUID).

Writing this I'm realizing that we probably need to involve the matching in the distance calculation too, since we need to aggregate all the distances recorded during the exposure, so duration and distance handling would be similar.

If we want the handling to be consistent with Android, were we have a mandatory timer, it seems we're left with recording duration/distance per TCN and aggregating during matching.

Another possibility may be changing the TCN protocol, e.g. making iOS behave like Android (refresh based on timer instead of read request). I've given this much thought yet.

@scottleibrand
Copy link
Contributor Author

“If we want the handling to be consistent with Android, were we have a mandatory timer, it seems we're left with recording duration/distance per TCN and aggregating during matching.”

This was my assumption about how it would work. Since we’re looking for closest distance, aggregation across TCNs could be as simple as taking the lowest distance value.

@ivnsch
Copy link
Collaborator

ivnsch commented Jul 9, 2020

Okay, an implementation could look like this:

Detection:

  • We keep a hash map with the detected TCNs TCN : { start_timestamp, min_distance, avg_distance }
  • We add a timer that each x minutes moves the entries from the map to the database. We can either do upsert (if exists, merge) or we just add always new rows and aggregate repeated TCNs during matching.
  • If the device goes out of range before that the timer fires or the app is stopped, the entries are also persisted. It may be possible to skip this step if the timer interval is small enough.

Matching:

  • We put all the matched entries ({ TCN, start_timestamp, min_distance, avg_distance, end_timestamp }) in a list.
  • We group entries in alerts, if they're contiguous (we'd have to determine a max delta between end_timestamp and start_timestamp).
  • The resulting alerts have the group's min/max timestamp and min/avg distance.

From here nothing changes, other than the alerts have a couple of new fields to display. Assuming that we don't want to link the alerts that come from the same sender but are far apart.

Thoughts?

@ivnsch
Copy link
Collaborator

ivnsch commented Jul 9, 2020

“If we want the handling to be consistent with Android, were we have a mandatory timer, it seems we're left with recording duration/distance per TCN and aggregating during matching.”

This was my assumption about how it would work. Since we’re looking for closest distance, aggregation across TCNs could be as simple as taking the lowest distance value.

Btw, just noting that this is mostly about duration. The realization was that we need to handle it similarly to distance (not only during matching), as on iOS a TCN may stand for very large periods of time (it may have been implied, as we probably are interested in time frames shorter than 15 mins).

@scottleibrand
Copy link
Contributor Author

Assuming that we don't want to link the alerts that come from the same sender but are far apart.

Elena was just asking about that in #ux, but I agree that feature can be deferred for a future version. https://coepi.slack.com/archives/CUR0KQRNG/p1594310201140100

@duskoo
Copy link
Collaborator

duskoo commented Jul 18, 2020

Okay, an implementation could look like this:

Detection:

  • We keep a hash map with the detected TCNs TCN : { start_timestamp, min_distance, avg_distance }
  • We add a timer that each x minutes moves the entries from the map to the database. We can either do upsert (if exists, merge) or we just add always new rows and aggregate repeated TCNs during matching.
  • If the device goes out of range before that the timer fires or the app is stopped, the entries are also persisted. It may be possible to skip this step if the timer interval is small enough.

Matching:

  • We put all the matched entries ({ TCN, start_timestamp, min_distance, avg_distance, end_timestamp }) in a list.
  • We group entries in alerts, if they're contiguous (we'd have to determine a max delta between end_timestamp and start_timestamp).
  • The resulting alerts have the group's min/max timestamp and min/avg distance.

From here nothing changes, other than the alerts have a couple of new fields to display. Assuming that we don't want to link the alerts that come from the same sender but are far apart.

Thoughts?

  1. I don't see the use case for avg_distance.
  2. "If the device goes out of range" - this does not seem relevant. How would we detect device exiting range anyway?
  3. Unclear how end_timestamp is determined. Maybe use: current_timestamp + validity_interval
    validity_interval could be ( 15min / 2 )
  4. "we'd have to determine a max delta between end_timestamp and start_timestamp" - 15min is the magic number used elsewhere.

@ivnsch
Copy link
Collaborator

ivnsch commented Jul 18, 2020

  1. I don't see the use case for avg_distance.
  2. "If the device goes out of range" - this does not seem relevant. How would we detect device exiting range anyway?
  3. Unclear how end_timestamp is determined. Maybe use: current_timestamp + validity_interval
    validity_interval could be ( 15min / 2 )
  4. "we'd have to determine a max delta between end_timestamp and start_timestamp" - 15min is the magic number used elsewhere.
  1. It was requested in the distance issue
  2. Yeah, not really necessary. I didn't do this in the PR (for the record, it's possible to detect).
  3. end_timestamp is the timestamp of the last recorded TCN, scoped to either the in-memory batches (short lived) or the database records. It's "expanded" when adding contiguous TCNs.
  4. The end_timestamp and start_timestamp threshold and timer to refresh TCNs on Android seem unrelated. The former answers "how much time does have to pass to consider exposures separate"? This seems mostly UX/health.

Btw, this spec was just a first draft, off the top of my head. The implementation has some changes (though mostly it matches it).

@duskoo
Copy link
Collaborator

duskoo commented Jul 19, 2020

  1. Ok.
  2. Ah, right: CBPeripheralState.disconnecting. We do have to persist all the entries from the map to DB, otherwise we are risking missing a contact/infection.
  3. Clear.
  4. Those are unrelated. But we need to pick a threshold value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants