-
-
Notifications
You must be signed in to change notification settings - Fork 756
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
contact trick #595
contact trick #595
Conversation
I'm going to add some details to the PR description (didn't have much time today). Also it still needs a pass or two of cleanup (for example, I suspect there are things that I put into the As of now, my biggest question would be this: am I doing things the right way in Another thing is the list of things that can be useful on a watch face. I added a bunch, but I've been using iAPS for just a couple of days, so I'm just guessing. Also need to double-check that the "stale" state is rendered correctly - with |
Another thing - I called the thing "Contact Trick" everywhere, which might be not the best name/label :) |
After that I think green/orange/red loop. Perhaps even IOB as on option. The loop and the IOB and the COB and all of the other loop status can all be retrieved from just the suggestion. I therefore don't think we need all of the other stuff or imported modules here, as we don't need to enact anything (don't need to communicate with pump), just retrieve the last suggestion. |
I suggest to start small, then we/you eventually can add stuff later. |
Thank you for your thoughts on this, Jon! I ended up setting up
Sounds good! I'll be removing things/imports (later today, hopefully). I also need to tweak the rendering a little bit, some things end up too small under certain circumstances - too hard to see inside a small circle. |
I think In fact, that's the biggest downside of this approach (and a risk), even though it hasn't happened a single time over the past two days of me running it. I think I should add some warning/description about this in the settings view. |
@Jon-b-m I pushed some tweaks-and-cleanups - removed most of the imports and subscriptions in the manager, dropped part of the "state" and tweaked the rendering a little bit. I will need to try it "live" to see if it looks good/is readable on the watch, but otherwise it all should be in a more or less decent state. |
@@ -11,6 +11,7 @@ class BaseProvider: Provider, Injectable { | |||
@Injected() var deviceManager: DeviceDataManager! | |||
@Injected() var storage: FileStorage! | |||
@Injected() var bluetoothProvider: BluetoothStateManager! | |||
@Injected() var contactTrickManager: ContactTrickManager! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure if I should have added this here - it's referenced from the ContactTrick.Provider
when contacts are saved
private func renderContacts() { | ||
contacts.forEach { renderContact($0) } | ||
workItem = DispatchWorkItem(block: { | ||
print("in updateContact, no updates received for more than 5 minutes") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
haven't looked yet into how to log things like this correctly
SuggestionObserver, | ||
SettingsObserver | ||
{ | ||
func glucoseDidUpdate(_: [BloodGlucose]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure if it's necessary to subscribe to glucose updates, or if subscribing to suggestions is enough
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess BG can also be retrieved from the suggestion, instead of asking self.coreDataStorage.fetchGlucose(...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but not trend
or delta
🤔
private var glucoseFormatter: NumberFormatter { | ||
let formatter = NumberFormatter() | ||
formatter.numberStyle = .decimal | ||
formatter.locale = Locale(identifier: "en_US") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added the locale explicitly here in order to make it print decimal separators as points (.
) not commas (,
), because It looked weird-ish on the complication, but it doesn't seem right to override the locale like this 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed it.
@@ -61,6 +61,9 @@ extension Settings { | |||
Text("Dynamic ISF").navigationLink(to: .dynamicISF, from: self) | |||
} header: { Text("Extra Features") } | |||
|
|||
Section { | |||
Text("Contact trick").navigationLink(to: .contactTrick, from: self) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right now the Contact Trick section is located in the main settings view, right above the Debug options
- not sure what's the right place for it
DispatchQueue.main.asyncAfter(deadline: .now() + 5 * 60 + 15, execute: workItem!) | ||
} | ||
|
||
private func renderContact(_ entry: ContactTrickEntry) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these larger functions are straight copy-pastes from the WatchManager
, it probably deserves a refactoring but I don't feel qualified for that :)
fontTracking: FontTracking, | ||
color: Color | ||
) { | ||
// guard let context = UIGraphicsGetCurrentContext() else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
commented out - just some stuff to help debugging, to be deleted
processQueue.async { | ||
let readings = self.coreDataStorage.fetchGlucose(interval: DateFilter().twoHours) | ||
let glucoseValues = self.glucoseText(readings) | ||
self.state.glucose = glucoseValues.glucose |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self.state
doesn't have to be an instance field in this class - I could create a new one every time and pass it along into renderContacts()
- but it was done like this in WatchManager
so I kept it the same
I was observing something just now - the ring was green (in the app), last update was 3 min ago, but on the contact picture it was yellow (and 8 minutes ago) - I did "force" the refresh of the contact, so it seems like my code was getting a wrong self.state.lastLoopDate = self.apsManager.lastLoopDate (it got fixed with the next cycle, so I didn't have a chance to investigate more) |
You don’t need APSmanager for this. Everything can be retrieved from suggestion. suggestion.timestamp |
I will take a closer look at this PR next week, I hope. As soon as I’m done with some other iAPS work. Thank you! |
Aha! Very good! :) |
Another thing I'm observing today - the contact pictures on the watch face are displaying the pictures from 5 hours ago, even though the contact manager was updating the contacts without problems. Tapping on the complication opens the contact - the picture is up-to-date there, as well as when looking at the contact on the phone. Not sure what has happened. Locking/unlocking the watch fixed it. |
I had to restart the watch to fix it. The contact pictures on the watch were not updating, or updating but with a very long delay. |
A quick update: I haven't seen any issues with contacts being out of date on the watch face since the last time I mentioned it here - works like a clock. |
…e using core data anyways
# Conflicts: # FreeAPS.xcodeproj/project.pbxproj
Now merged into dev via another branch, as I had to make some small edits after testing. Thank you @yurique |
This PR introduces a new feature for those of us who are using an Apple Watch.
I don't know who to give credit for the original idea, I first heard of it in the xdripswift project: JohanDegraeve/xdripswift#481 and before that, it was implemented in OpenGlück: https://github.com/open-gluck#the-contact-trick
Here, though, the implementation and offered features are much more flexible and configurable:
Multiple contacts
We can configure multiple contacts, and then add add them all to the watch face - so we can see more information. One contact provides too little space to reliably display more than a single number and maybe an indicator. Multiple contacts help with this.
Layouts
There are two layouts that can be configured (this is debatable - we can leave just one, to make configuration simpler).
single
- the main layout, where we can configure a main piece of information to display (it will take the central, largest part of the image), and - optionally - two secondary pieces: top and bottom (which will take less space and will be smaller)split
- this layout will display two pieces of information in two equally sized parts of the image - top and bottomRings
In addition to the above, we can configure up to two optional "large" rings that will be drawn around the image (similar to what Apple offers in its weather-related complications, or in the activity tracker complication)
A ring can be one of the following:
loop status
- the well known green/yellow/red ringiob
- the fraction of current IOB relative to the max IOBcob
- the fraction of current COB relative to the max COBiobcob
- a "double" ring; left side - IOB, right side - COB"Pieces"
Every area can be configured to display one of the following values:
Extra customizations
In addition to the above, the following is configurable:
Downsides / important to know
Unlike calendar events, the contact picture doesn't have an expiration time: so if something happens (iAPS crashes or something else) - the contact picture will stay there "forever" and will become misleading. Therefore I would recommend having one "contact" to display the time of the latest loop (that's what I'm doing myself).
Watch battery life? I haven't noticed any significant differences over the past couple of days. But I would guess constant contact updating might drain the battery a little bit faster than normal.
The white ring around the contact picture - unfortunately, that's part of the Apple's Contact complication design. It's always there - eating up precious screen estate - and no way to change it ¯_(ツ)_/¯
Screenshots