burnedikt / diasend-nightscout-bridge

Synchronize your diasend data to nightscout.
MIT License
18 stars 18 forks source link

Glucose Values Are Off #2

Closed boethius closed 2 years ago

boethius commented 2 years ago

First of all, thank you for creating this!

It seems the Glucose values are off by ~1 mmol/l for some reason. I can find anything that would correlate to what is being pulled/pushed from Diasend.

Thanks!

burnedikt commented 2 years ago

Hey @boethius, thanks for checking out this project. I must admit I only tested the project with mg/dl so far and the blood glucose values are also only fetched from diasend in mg/dl (see https://github.com/burnedikt/diasend-nightscout-bridge/blob/7249e26b534020179be0f5d66896e0eed271dd3b/diasend.ts#L75).

You could try changing that to mmol_l to obtain the values directly from diasend with the correct unit?

burnedikt commented 2 years ago

I've put up a PR that allows to specify which unit to use for glucose values both on diasend and nightscout: https://github.com/burnedikt/diasend-nightscout-bridge/pull/3.

However, in my tests, there was no discrepancy between the values in mmol/l or mg/dl. Would've also been quite surprising as the conversion is pretty straight forward. Still, you might want to give it a try on your end as well.


Since this doesn't seem to be a mere issue of unit conversions, another thing to look at would be the timings: The diasend API does not return any timezone information for the CGM readings but nightscout expects a timezone (as it works with ISO8601 formatted date strings). This project therefore simply takes the date and time returned from diasend and stupidly puts it into the "local" timezone, which is the timezone of the machine running the bridge / nodejs code.

This in turn could lead to an offset in the datetimes and since the values are put to wrong times, it could also explain why there's a discrepancy between the values shown in nightscout and diasend as appears to be the case for you:

As an example: Diasend just returns the following information about the date and time of a glucose reading: 2022-08-20T01:03:29. Now if this project / NodeJS is run in timezone Europe/Berlin, it will assume that the reading indeed happened 3 minutes past 1 o'clock in the morning in Berlin timezone and will forward this value to nightscout (now including the timezone). I haven't yet figured out how diasend attempts to figure out the timezone but generally, the timezone in which the glucose readings are returned from diasend could be different. To verify, you could run the bridge in "check"-mode, i.e. not sending anything to nightscout and just outputting the values to the terminal by running yarn test-run, then compare whether the times sent to nightscout appear correct.

burnedikt commented 2 years ago

reopening this as still awaiting feedback

boethius commented 2 years ago

@burnedikt thanks for the prompt response. The problem was the local time on the server, as that was set to UTC. Normally within this space, the timezone is less important in contrast to what time of day, so sending the values without timezone logic would do the trick. Or just not assuming the timezone of the server is the same as the timezone your are pushing to.

burnedikt commented 2 years ago

so sending the values without timezone logic would do the trick

Yeah, but sadly, the nightscout API (and generally Javascript) always puts the date and time in the context of the configured timezone, i.e. if you send the date and time as "2022-08-20T12:50:00" to nightscout (because that seems right in your GMT+2 timezone, without specifying a timezone) but nightscout is running configured at UTC, it will assume your date and time are already in UTC time and you'll end up with a local date and time of "2022-08-20T14:50:00" (i.e. 2 hours ahead). If you don't specify a timezone / utc offset, it will just assume you gave the time in UTC. This is actually reasonable behaviour, but diasend does not send the time in UTC but a different timezone which makes it hard.

From the nightscout api docs:

Required timestamp when the record or event occured, you can choose from three input formats

  • Unix epoch in milliseconds (1525383610088)
  • Unix epoch in seconds (1525383610)
  • ISO 8601 with optional timezone ('2018-05-03T21:40:10.088Z' or '2018-05-03T23:40:10.088+02:00')

The date is always stored in a normalized form - UTC with zero offset. If UTC offset was present, it is going to be set in the utcOffset field.


So the issue is, that the times provided by diasend do not contain timezone information (which would lead one to assume UTC), but actually, they are in a certain timezone. To not assume the timezone of the server, we'd need to send the date and time as UTC but to do that, we'd need to figure out in which timezone the diasend dates and times are defined so that we convert to UTC and not have a mess.

I might have found one way to make this less painful by checking the Date header returned by the diasend server and identifying its timezone and then putting all dates and times returned by diasend into that timzeone. Will try this out shortly.

burnedikt commented 2 years ago

I might have found one way to make this less painful by checking the Date header returned by the diasend server and identifying its timezone and then putting all dates and times returned by diasend into that timzeone. Will try this out shortly.

Wasn't successful, sadly. So for now, I am left with diasend sending all dates and times in "local time", but it's unclear how it determines which is the local timezone ... Without that information, any user of this project needs to correctly setup the timezone on the machine that runs this project, otherwise, there will be an offset as soon as pushing the data to nightscout. I will for now add this as a known issue to the documentation as I am out of ideas on how to fix it with the current diasend API.

burnedikt commented 2 years ago

Documentation made in https://github.com/burnedikt/diasend-nightscout-bridge/commit/3cfb623801d7487c61f47e1eed4eeb58c200d511