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

Bluetooth Heartbeat #351

Merged
merged 29 commits into from
Jan 27, 2025
Merged

Bluetooth Heartbeat #351

merged 29 commits into from
Jan 27, 2025

Conversation

bjorkert
Copy link
Contributor

@bjorkert bjorkert commented Jan 13, 2025

What's New:

  • Bluetooth Heartbeat: Introducing a Bluetooth-driven heartbeat using RileyLink (and compatible devices) or Dexcom G6/ONE/G7/ONE+ devices. This offers a more battery-efficient alternative to the silent tune. While generally reliable, the silent tune can sometimes be interrupted, causing LoopFollow to stop functioning. If you've been experiencing significant battery drain or issues with the silent tune, try the Bluetooth heartbeat. Note: This requires a constant Bluetooth connection to your device. If the silent tune is working well for you, there's no need to change.
  • Logging to File with Internal Viewer: LoopFollow now logs activity to a file, viewable within the app with filtering and search capabilities. This will aid in troubleshooting and diagnostics. You can also share the log if needed. What is being logged will be expanded in future versions.
  • Timer Refactoring and Background Optimizations: Timers have been refactored, and background tasks have been optimized to reduce battery usage.
  • Increased Background Failure Notifications: The number of notifications you receive if the app stops updating has been increased. You'll now receive notifications at 6, 12, and 18 minutes after a failure.

@bjorkert bjorkert requested a review from marionbarker January 13, 2025 17:57

case .dexcomG7:
if let name = device.name {
return name.hasPrefix("DXCM") || name.hasPrefix("DX02")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you change this to be "DX", I believe it will pick up any Dexcom transmitter. G6 or G7, ONE or ONE+ or Stelo. But that would need to be tested. Maybe @MikePlante1 could try this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might have other UUID-Strings, need to test that. I think i have an old G6 somewhere to test with. I can add it later on (after merge).

@marionbarker
Copy link
Collaborator

Test Part 1:

When I first built the app, I was asked if I wanted to allow Bluetooth - said yes.

View Logs

Tapped on settings and used new View Logs and Share Logs.
Both work as expected.
Allow the logs to get a little more interesting and then come back.

Suggestion Expand on the log name to include LoopFollow and/or the display name. 2025-01-15.log is not sufficiently descriptive.

Test with used G7 sensor

Tapped on settings and used new Background Refresh Settings to select G7/ONE+ and then to select a sensor I took off yesterday

I can see the connect/disconnect in the Xcode log file:

##### scheduled BG task in 299.0 seconds
[08:04:54] [Bluetooth] Connected to: Optional("DXCMvu")
[08:05:04] [Bluetooth] Disconnect from: Optional("DXCMvu")
[08:05:53] [Bluetooth] Connected to: Optional("DXCMvu")
[08:06:04] [Bluetooth] Disconnect from: Optional("DXCMvu")

I will let that run for a while with app in background using a glucose trace that will trigger low and high alarms.

@bjorkert
Copy link
Contributor Author

Log file name does now include LoopFollow in order to be more descriptive. 6c0fd1b

@marionbarker
Copy link
Collaborator

marionbarker commented Jan 15, 2025

Comment - more testing is coming

Do we expect LoopFollow to wake up and show the alarms or just the notification banner?

This test is with an iPhone 7 running iOS 15.8.3.

I am not sure if this is an iOS 15 limitation, but the LF app did not come out of background mode to report a high glucose.
I'm also seeing this in the Xcode debug log:

2025-01-15 10:18:02.311369-0800 Loop Follow[89527:9205570] Connection 136: received failure notification
2025-01-15 10:18:02.311988-0800 Loop Follow[89527:9205570] [connection] nw_flow_add_write_request [C136.1 35.192.62.91:443 failed channel-flow (satisfied (Path is satisfied), viable, interface: en2, ipv4, ipv6, dns)] cannot accept write requests
2025-01-15 10:18:02.312154-0800 Loop Follow[89527:9205570] [connection] nw_write_request_report [C136] Send failed with error "Socket is not connected"

@dsnallfot
Copy link
Contributor

dsnallfot commented Jan 16, 2025

Disclaimer: I have not tested that all background enactment of alarms works as expected (regarding Marion's observations in the previous post) since I've been running my regular LF with silent audio and all alarms as usual in parallell with this BT PR in a separate instance.

My observations so far during 24h+ testing:

  • Tested connection to several Dexcom G7 and switch between devices works flawlessly. 1 single missed BT connection during the testing period, which swiftly returned at the next heartbeat

  • orangelink/Rileylink works even better with 1 min ping and strong BT signal. Seamless switching between devices (orangelink 1 -> orangelink 2 - > G7 and so on)

  • The new logging feature is also great. Very useful to see real time info for relevant parts of the apps operation without the need to be hooked up to Xcode.

  • But the absolutely greatest benefit here is the reduced battery consumption. Since I run parallel instances in production on my phone right now, and I got more than 24h of usage I can direct compare the battery usage to get an idea of the potential here.

Note: "Loop Follow TRC" is the BT heartbeat instance in the screenshots

I've been using it active on screen more than my regulate Loop Follow instance during the last 24h testing which probably makes the relative battery usage for the BT heartbeat instance higher than it would be in a non testing situation.

And most of the 24h I've been using 1 minute ping through Orangelink, waking the app more frequently vs if using a G7.

With that said. There is no doubt that BT heartbeat uses significantly less battery than silent audio.

% Time
image image

Any downsides with BT heartbeat?

  1. You need to (remember to) carry an additional BT device on you all the time
  • But the G7 is so small, it could easily be attached to the iPhone case with some double-sided tape without obscuring mag safe charging.

  • And the orangelink/rileylink has such great BT signal it could cover a large area (home) and fits in any pocket when out of the home.

  • If you should forget the BT device when heading out, you can easily switch back to silent audio mode for the time being.

  1. BT heartbeat timing is controlled by the BT device and can create gaps between when the looper you're following uploads reading and when your LF wakes up to fetch them.
  • This is most noticeable with a G7 that only transmit every 5 minutes (ie worst case scenario is that you could get almost 5 minutes delayed updates if the timing is bad)

  • Orangelink/Rileylink 1 min update makes this issue much smaller, but still can cause almost a minute delay with bad timing

Timing issue mitigation?

  • Orangelink: The 1 min heartbeat can be quite easily timed by connecting the Orangelink to LF a few seconds after the Looper uploads readings to NS.

  • G7: I spent a few hours today experimenting with cutting a couple of G7 sensors open, to see if it's possible to either reset the magnet contact switch or reboot by power off/on the battery (or even change the battery) to modify at which second the heartbeat is being sent. But any tampering with the battery seems to kill the sensor (ie it will not send any more heartbeats after the power has been cut and reconnected). This is probably by design by dexcom to prevent this kind of tampering. There maybe is a way to achieve a reboot somehow, but at least I wasn't successful in my experimentation today.

  • This means that the G7 timing needs to happen when the next sensor is physically applied to and activated on the looper. This will require more experimentation before I can say exactly at what second this should happen to minimize the upload/fetching gap.

Summary:

This is an incredible great addition to LF that solves the long running high battery consumption issue caused by the silent audio hack needed to keep the app awake in the background.

Great job Jonas!

@aidanlane
Copy link

Wow, this is exciting!

Perhaps a dumb question, but is there any way Loop Follow could use my Apple Watch for the Bluetooth heartbeat?

@dsnallfot
Copy link
Contributor

dsnallfot commented Jan 18, 2025

Perhaps a dumb question, but is there any way Loop Follow could use my Apple Watch for the Bluetooth heartbeat?

I've been fine combing the internet to see if someone has figured out a way to use Apple Watch as a mean to automatically wake up apps in background on an iPhone - but, without success...

Please let Jonas know if you find something regarding this anywhere (Most of how different Apple devices communicate between each other is not publicly available code)

@marionbarker
Copy link
Collaborator

I updated my 4 phones to the most recent version. All are working as expected.

I also captured some screenshots for use with the documentation.

The graphic below shows steps to selecting Background Refresh Type:

loopfollow-bluetooth-config

The graphic below shows the steps if you choose to use a Dexcom transmitter (G6/ONE/Anubis) or sensor (G7/ONE+). This can be a device that has expired but still has an active battery. If the person using Follow is also wearing a sensor, they should choose their own sensor. Behavior is similar for the RileyLink option. The RSSI is a measure of the strength of the signal. It is normal for the Dexcom device to disconnect. It will reconnect regularly.

loopfollow-dexcom-example

@marionbarker
Copy link
Collaborator

I tested again with 3 test phones and 1 real phone with the latest commit, a819fe1.

All continues to work smoothly. (I did not do any battery testing.)

Copy link
Collaborator

@marionbarker marionbarker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on code review and testing.

@marionbarker marionbarker merged commit ae5f5c0 into dev Jan 27, 2025
@marionbarker marionbarker deleted the bt-heartbeat branch January 30, 2025 16:25
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

Successfully merging this pull request may close these issues.

4 participants