Skip to content

Commit

Permalink
add new module: dexcom
Browse files Browse the repository at this point in the history
  • Loading branch information
lasers committed Jan 16, 2024
1 parent 89b5e8e commit b78ccab
Showing 1 changed file with 150 additions and 0 deletions.
150 changes: 150 additions & 0 deletions py3status/modules/dexcom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
r"""
Display glucose readings from your Dexcom CGM system.
Dexcom CGM systems provide glucose readings up to every five minutes, all with
zero fingersticks required for calibration or mealtime dosing. Designed to help
diabetes patients keep track of their blood glucose levels with ease.
Configuration parameters:
format: display format for this module
*(default "Dexcom [\?color=mg_dl {mg_dl} mg/dL {trend_arrow}] [\?color=darkgrey {datetime}]")*
format_datetime: specify strftime characters to format (default {"datetime": "%-I:%M %p"})
ous: specify whether if the Dexcom Share user is outside of the US (default False)
password: specify password for the Dexcom Share user (default None)
user: specify username for the Dexcom Share user, not follower (default None)
thresholds: specify color thresholds to use
*(default {
"mg_dl": [(55, "bad"), (70, "degraded"), (80, "good"), (130, "degraded"), (180, "bad")],
"mmol_l": [(3.1, "bad"), (3.9, "degraded"), (4.4, "good"), (7.2, "degraded"), (10.0, "bad")],
})*
Format placeholders:
{mg_dl} blood glucose value in mg/dL, eg 80
{mmol_l} blood glucose value in mmol/L, eg 4.4
{trend} blood glucose trend information, eg 4
{trend_direction} blood glucose trend direction, eg Flat
{trend_description} blood glucose trend information description, eg steady
{trend_arrow} blood glucose trend as unicode arrow, eg →
{datetime} glucose reading recorded time as datetime
format_datetime placeholders:
key: epoch_placeholder, eg {datetime}
value: % strftime characters to be translated, eg '%b %d' ----> 'Jan 1'
Color thresholds:
xxx: print a color based on the value of `xxx` placeholder
Requires:
pydexcom: A simple Python API to interact with Dexcom Share service
Note:
IF GLUCOSE ALERTS AND CGM READINGS DO NOT MATCH SYMPTOMS OR EXPECTATIONS,
USE A BLOOD GLUCOSE METER TO MAKE DIABETES TREATMENT DECISIONS.
Examples:
```
# compact
dexcom {
format = "\?color=darkgrey [\?color=mg_dl {mg_dl} {trend_arrow}] {datetime}"
format_datetime = {"datetime": "%-I:%M"}
}
```
@author lasers
SAMPLE OUTPUT
[
{"full_text": "Dexcom "},
{"full_text": "80 mg/dL →", "color": "#00FF00"},
{"full_text": "7:15 PM", "color": "#A9A9A9"}
]
"""

from pydexcom import Dexcom
from datetime import datetime as dt, timedelta as td


class Py3status:
""" """

# available configuration parameters
format = r"Dexcom [\?color=mg_dl {mg_dl} mg/dL {trend_arrow}] [\?color=darkgrey {datetime}]"
format_datetime = {"datetime": "%-I:%M %p"}
ous = False
password = None
thresholds = {
"mg_dl": [
(55, "bad"),
(70, "degraded"),
(80, "good"),
(130, "degraded"),
(180, "bad"),
],
"mmol_l": [
(3.1, "bad"),
(3.9, "degraded"),
(4.4, "good"),
(7.2, "degraded"),
(10.0, "bad"),
],
}
user = None

def post_config_hook(self):
for x in ["user", "password"]:
if not getattr(self, x):
raise Exception(f"missing {x}")

# fmt: off
self.placeholders = [
"datetime", "mg_dl", "mmol_l", "trend", "trend_arrow", "trend_description", "trend_direction",
]
# fmt: on

self.init = {"datetimes": []}
for word in ["datetime"]:
if self.py3.format_contains(self.format, word) and word in self.format_datetime:
self.init["datetimes"].append(word)

self.thresholds_init = self.py3.get_color_names_list(self.format)
self.dexcom_class = Dexcom(self.user, self.password, ous=self.ous)

def _get_dexcom_data(self):
glucose_reading = self.dexcom_class.get_current_glucose_reading()
data = {x: getattr(glucose_reading, x) for x in self.placeholders}
data["datetime"] = data["datetime"].isoformat()
return data

def _get_cached_until(self, data):
timestamp = dt.fromisoformat(data["datetime"])
return ((timestamp + td(minutes=5, seconds=5)) - dt.today()).total_seconds()

def dexcom(self):
dexcom_data = self._get_dexcom_data()
cached_until = self._get_cached_until(dexcom_data)

for word in self.init["datetimes"]:
if word in dexcom_data:
tmp_str = dt.strftime(
dt.fromisoformat(dexcom_data[word]), self.format_datetime[word]
)
dexcom_data[word] = self.py3.safe_format(tmp_str)

for x in self.thresholds_init:
if x in dexcom_data:
self.py3.threshold_get_color(dexcom_data[x], x)

return {
"cached_until": self.py3.time_in(cached_until),
"full_text": self.py3.safe_format(self.format, dexcom_data),
}


if __name__ == "__main__":
"""
Run module in test mode.
"""
from py3status.module_test import module_test

module_test(Py3status)

0 comments on commit b78ccab

Please sign in to comment.