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

effected temp basal amounts #5740

Closed
wants to merge 4 commits into from
Closed

Conversation

bewest
Copy link
Member

@bewest bewest commented Jul 5, 2020

#4971

  • For loop/omnipod users, nightscout does not correctly calculate effected temp basal amounts for omnipod
  • Loop users as of September 2019 updates have new data in the form of .amount contains effected rate

Impacts nightscout reports for loop/omnipod users and becomes detectable comparing reports or even adding things up manually.
It looks to me like the issue in the daytoday reports traces through to line 369 in getTempBasal.

There are 18 other places that similarly use .absolute and conceivably some of them will need a similar patch or update to use a method to calculate effected rates. Thoughts?

lib/client/careportal.js:279:      data.absolute = Number(absolute);
lib/client/careportal.js:415:    pushIf('absolute' in data, translate('Basal value') + ': ' + data.absolute);
lib/client/renderer.js:1171:          .text((t.percent ? (t.percent > 0 ? '+' : '') + t.percent + '%' : '') + (isNaN(t.absolute) ? '' : Number(t.absolute).toFixed(2) + 'U') + (t.relative ? 'C: +' + t.relative + 'U' : ''));
lib/plugins/basalprofile.js:86:        !isNaN(basalValue.treatment.absolute) ? basalValue.treatment.absolute + 'U/h' : '';
lib/plugins/bgnow.js:166:      recent.mean - delta.absolute / delta.elapsedMins * 5 : recent.mean - delta.absolute;
lib/plugins/bgnow.js:191:      info.push({label: translate('Absolute Delta'), value: sbx.roundBGToDisplayFormat(sbx.scaleMgdl(delta.absolute)) + ' ' + sbx.unitsLabel});
lib/plugins/treatmentnotify.js:148:      (!isNaN(lastTreatment.absolute) ? '\n' + translate('Value') + ': ' + lastTreatment.absolute + 'U' : '')+
lib/profilefunctions.js:368:    if (treatment && !isNaN(treatment.absolute) && treatment.duration > 0) {
lib/profilefunctions.js:369:      tempbasal = Number(treatment.amount || treatment.absolute);
lib/report_plugins/daytoday.js:674:          //            .text((t.percent ? (t.percent > 0 ? '+' : '') + t.percent + '%' : '') + (t.absolute ? Number(t.absolute).toFixed(2) + 'U' : ''));
lib/report_plugins/treatments.js:133:    pushIf(!isNaN(data.absolute), translate('Basal value') + ': ' + data.absolute);
lib/report_plugins/treatments.js:205:            data.absolute = $('#rped_absolute').val();
lib/report_plugins/treatments.js:213:            if (data.absolute === '') {
lib/report_plugins/treatments.js:214:              delete data.absolute;
lib/report_plugins/treatments.js:241:        $('#rped_absolute').val('absolute' in data ? data.absolute : '');
lib/report_plugins/treatments.js:334:        .append($('<td>').attr('align','center').append('absolute' in tr ? tr.absolute.toFixed(2) : ''))
lib/server/treatments.js:169:  obj.absolute = Number(obj.absolute);
lib/server/websocket.js:315:             if (data.data.absolute) {
lib/server/websocket.js:316:              query_similiar.absolute = data.data.absolute;

bewest added 4 commits July 5, 2020 09:07
See issue #4971 for more information.
#4971

* Insulin pump vendors vary in the timing between insulin dosings.
* When modifying temp basal rates every 5 minutes, the differences between dose
  timings inherent in the pump delivery mechanisms become noticeable.
* Timing issue is mitigated by creating a model for each pump and calculating
  the impact of each timing difference.
* The result is a new piece of data: the effected insulin rate over an
  arbitrary period of time, eg 4 minutes and 57 seconds.
* The new piece of data is uploaded via the `amount` parameter for Loop users
  as of September 2019.

This patch favors the `amount` parameter when calculating effected temp basal
rates.
Apply same patch for looking at effected temp basal amount preferentially
through the `amount` field.  This targets the text rendering of the amount
printed on the basal line.
Apply same patch as others in line with checking for amount.
See pull request #574 for more info.
This patch should adjust the last treatment plugin to preferentially use amount
of last treatment when available instead of `absolute` so that effected temp
basal is accurately communicated.
Preferentially use `amount` field when available over `absolute`.
See #5740 for more information.

#5740
@bewest
Copy link
Member Author

bewest commented Jul 5, 2020

I've audited all the places mentioned above and have questions about these two:

Treatments

Should default treatments that are uploaded be forced to have an amount field? I think no: it would defeat the patches added so far that will only use it when available.

https://github.com/nightscout/cgm-remote-monitor/blob/dev/lib/server/treatments.js#L169

Websocket Query

Should websocket be able to query by amount? Maybe?

https://github.com/nightscout/cgm-remote-monitor/blob/dev/lib/server/websocket.js#L315

@sulkaharo
Copy link
Member

Sorry for comment lag - I'd very much prefer an approach where 1) we try to get the data formats unified across clients rather than supporting client quirks in the server (so this would be changed in Loop, not NS), and 2) if we support multiple data formats, we'd centralise data normalization to one part of the code such as the data loader, so the application logic only needs to know of one data format. If we go with the approach you have here (support multiple fields across the codebase) that easily leads to bugs, as devs would have to remember to use both fields at all times and it's then also a matter of time before someone adds a third field with the same data and adding support for that would be significantly easier if we have just one place where we add the field. Related, check the data formats specified in the V3 API; for maintainability it'd be great if we aim to not expand the feature set of the v1 api and modify the accepted data formats, vs encourage clients to migrate to v3.

@bartsluimer
Copy link

@ps2 would it be possible to have a look?

@bewest
Copy link
Member Author

bewest commented Jul 22, 2020

Thanks for the good criticism @sulkaharo, I think I agree with your reasoning.
Do you mean 1.) Loop should be submitting correct amount instead of adding a second "more correct" version of absolute? I agree, @ps2 can you add any detail on why adding the new absolute field is needed instead of assigning the correct value to amount? (This would have been prior to September 2019).

2.) I saw a place to do this during my audit, but it changes the logic in this patch, which depends on absence by default.

@ps2
Copy link
Contributor

ps2 commented Jul 22, 2020

@bewest Super happy to see someone tackling this! I'm not 100% sure I understand your question, but I can explain the reasoning behind sending the original scheduled rate and a total delivery amount. Users get confused (as we have seen in Tidepool web) if we display a rate that was different from what they saw being scheduled, or even weirder, a rate the pump doesn't actually support.

For example: If Loop schedules a 1.2U/hr basal which ends up running for 5.5 minutes on an Omnipod, the pod will deliver 2 x 0.5 clicks, or 0.1U of insulin. If the timeline shows 1.09090909 U/hr (0.1U over 5.5m = 1.09090909 U/hr), instead of 1.2 U/hr, that's a very confusing experience. It's useful to have both pieces of information: the original scheduled rate, and the actual delivery. Reversing out the calculation of a rate from a delivery amount and time period produces numbers that can be unexpected and confusing for users.

@ps2
Copy link
Contributor

ps2 commented Jul 22, 2020

Also, an absolute "rate" of 1.09090909 U/hr is not even the actual rate of delivery happening then; that's just the average rate over those 5.5 minutes, so it's additionally misleading.

I've made a lot of code updates in Loop to track these things separately. In retrospect (and I believe this statement applies to both code bases), it would have been better for the model to contain programmedRate, and totalDelivery. Those names are clear to future developers, and keep the needed distinction.

@marionbarker
Copy link

@bewest Thanks for working on this.

I saw the comment from @sulkaharo

we try to get the data formats unified rather than supporting client quirks in the server  (so this would be changed in Loop, not NS)

I believe there is an underlying design issue that probably "grew" as NS reports were added with underlying assumptions that don't match some newer real-world use cases. (And I'm not trying to throw darts here - I completely understand how this happens.)

I'm assuming that this is understood, but just in case, I'll belabor the point. There is no pump on the planet that provides continuous insulin drip and therefore calculating the amount of insulin delivered as rate times duration for a basal will always be an estimate. It is typically an overestimate for omnipod (because Insulet designed the pod to deliver its smallest increment at the end of a time unit - not the mid-point like Medtronic). I don't know about any other pump that might have data uploaded to Nightscout. I don't know if the folks supporting Omnipod for AAPS (or other instantiations for Omnipod) are uploading an amount in addition to rate and duration, but it seems reasonable to me for this to be supported by NS if it is provided.

Regarding the second comment:

2) if we support multiple data formats, we'd centralise data normalization to one part of the code such as the data loader, so the application logic only needs to know of one data format.

This is great - can we add into this that profiles be used too. At the current time, many of the NS reports only use the current profile which leads to inaccurate reports for daily insulin dosing, independent of the basal amount errors.

I think that a lot of the design of NS reports assume rate*duration is a valid estimate for amount to be added or subtracted from the scheduled basal using the current, rather than the time-relevant, profile. Seems like a pretty far reaching problem in report design.

Thanks to all
BTW - I use Nightscout for many things (just not for daily dose records). It's incredibly valuable, but could be even better.

@sulkaharo
Copy link
Member

Apologies for the delay - #5980 now does the data normalization of the amount/absolute fields on runtime data load, which solves the immediate issue for every usage in the codebase except reports with less new logic overall. Note that in this PR, some of the changes would not work as the code is inside code blocks that are not reached if the absolute data field is missing, so I think data normalization is the way to go (and this includes changes a bunch of things in the codebase; this is not Loop specific any way).

@sulkaharo sulkaharo closed this Jan 17, 2021
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.

5 participants