Compare commits

..
4 Commits
Author SHA1 Message Date
James Woglom 86e07880a9 bump to v0.8.3 2022-08-24 12:28:43 -04:00
Jarred YawandJames Woglom 751087373c fix unknown therapy event error in ciq_therapy_event.py 2022-08-24 12:20:45 -04:00
Ryan StutsmanandJames Woglom f47421e482 Replace hand-rolled date format with isoformat().
Fixes #47.
2022-08-22 16:45:46 -04:00
t1diotacandJames Woglom dfc39d61bb Update README.md
- Added sections on creating a user-specific install and crontab.
- Added bullet points on installing on CentOS/RHEL/Rocky Linux 8
2022-08-19 10:31:39 -04:00
6 changed files with 96 additions and 12 deletions
+17 -3
View File
@@ -116,7 +116,10 @@ First, ensure that you have **Python 3** with **Pip** installed:
* **On MacOS:** Open Terminal. Install [Homebrew](https://brew.sh/), and then run `brew install python3`
* **On Linux:** Follow your distribution's specific instructions.
For Debian/Ubuntu based distros, `sudo apt install python3 python3-pip`
- For Debian/Ubuntu based distros, `sudo apt install python3 python3-pip`
- For CentOS/Rocky Linux 8:
- `sudo dnf install python39-pip`
- `sudo alternatives --set python /usr/bin/python3.9`
* **On Windows:** Install Ubuntu under the [Windows Subsystem for Linux](https://ubuntu.com/wsl).
Open the Ubuntu Terminal, then run `sudo apt install python3 python3-pip`.
Perform the remainder of the steps under the Ubuntu environment.
@@ -126,6 +129,12 @@ Now install the `tconnectsync` package with pip:
```
$ pip3 install tconnectsync
```
To install into a user environment instead of system-wide for a more contained install:
````
$ pip3 install --user tconnectsync
````
- This will place the tconnectsync binary file at ``/home/<username>/.local/bin/tconnectsync``
If the pip3 command is not found, run `python3 -m pip install tconnectsync` instead.
@@ -377,13 +386,18 @@ invoking tconnectsync with no arguments via cron.
If using Pipenv or a virtualenv, make sure that you either prefix the call to main.py with `pipenv run` or source the `bin/activate` file within the virtualenv, so that the proper dependencies are loaded. If not using any kind of virtualenv, you can instead just install the necessary dependencies as specified inside Pipfile globally.
An example configuration in `/etc/crontab` which runs every 15 minutes:
An system-wide example configuration in `/etc/crontab` which runs every 15 minutes, on the 15 minute mark:
```bash
# m h dom mon dow user command
0,15,30,45 * * * * root /path/to/tconnectsync/run.sh
```
An example of a user crontab `crontab -e` if not running system-wide, which runs every 15 minutes:
```
*/15 * * * * /path/to/tconnectsync/run.sh
```
You can use one of the same `run.sh` files referenced above, but remove the `--auto-update` flag since you are handling the functionality for running the script periodically yourself.
## Tandem APIs
@@ -417,4 +431,4 @@ tconnectsync.util.cli.enable_logging()
api = tconnectsync.util.cli.get_api()
# Make API calls, e.g.
therapy_timeline = api.controliq.therapy_timeline('2022-08-01', '2022-08-10')
```
```
+1 -1
View File
@@ -1,6 +1,6 @@
[metadata]
name = tconnectsync
version = 0.8.2
version = 0.8.3
author = James Woglom
author_email = j@wogloms.net
description = Syncs Tandem t:connect pump data to Nightscout for the t:slim X2
+66 -2
View File
@@ -51,12 +51,52 @@ class CGMTherapyEvent(TherapyEvent):
},
"""
@classmethod
def parse(self, json):
def parse(_, json):
self = CGMTherapyEvent()
TherapyEvent.parse(self, json)
self.eventID = json['eventID']
self.egv = json['egv']['estimatedGlucoseValue']
return self
class BGTherapyEvent(TherapyEvent):
eventID = None
egv = None
"""
{
'bg': 160, # note in EGV
'cgmCalibration': 1, # not in EGV
'description': 'BG',
'deviceType': 't:slim X2 Insulin Pump',
'eventDateTime': '2022-08-20T07:25:24',
'eventTypeId': 16,
'indexId': 844955,
'interactive': 0,
'iob': 0.75,
'note': { 'active': False,
'eventId': 0, # different location than EGV
'eventTypeId': 16,
'id': 0,
'indexId': '',
'sourceRecordId': 0},
'requestDateTime': '0001-01-01T00:00:00',
'serialNumber': 'xxx',
'sourceRecId': 793549667,
'tempRateActivated': 0,
'tempRateCompleted': 0,
'tempRateId': 0,
'type': 'BG',
'uploadId': 748700213}
"""
@classmethod
def parse(_, json):
self = BGTherapyEvent()
TherapyEvent.parse(self, json)
self.eventID = json['note']['eventId']
# This is probably not how we want to provide CGM calibrations to Nightscout,
# but will just include it as egv data for now to keep the thing from crashing :)
self.egv = json['bg']
return self
class BolusTherapyEvent(TherapyEvent):
bolusRequestOptions = None
REQUEST_AUTOMATIC = "Automatic Bolus/Correction"
@@ -364,4 +404,28 @@ class BolusTherapyEvent(TherapyEvent):
"tempRateCompleted": 0,
"tempRateActivated": 0
}
"""
CGM Calibration (Therapy Event Type BG):
{ 'bg': 160,
'cgmCalibration': 1,
'description': 'BG',
'deviceType': 't:slim X2 Insulin Pump',
'eventDateTime': '2022-08-20T07:25:24',
'eventTypeId': 16,
'indexId': 844955,
'interactive': 0,
'iob': 0.75,
'note': { 'active': False,
'eventId': 0,
'eventTypeId': 16,
'id': 0,
'indexId': '',
'sourceRecordId': 0},
'requestDateTime': '0001-01-01T00:00:00',
'serialNumber': 'xxx',
'sourceRecId': 793549667,
'tempRateActivated': 0,
'tempRateCompleted': 0,
'tempRateId': 0,
'type': 'BG',
'uploadId': 0}
"""
+1 -1
View File
@@ -11,7 +11,7 @@ from .api.common import ApiException
from .parser.nightscout import ENTERED_BY
def format_datetime(date):
return arrow.get(date).strftime('%Y-%m-%d %H:%M:%S')
return arrow.get(date).isoformat()
def time_range(field_name, start_time, end_time):
arg = ''
+8 -4
View File
@@ -1,4 +1,4 @@
from tconnectsync.domain.therapy_event import BolusTherapyEvent, CGMTherapyEvent
from tconnectsync.domain.therapy_event import BolusTherapyEvent, CGMTherapyEvent, BGTherapyEvent
from tconnectsync.parser.tconnect import TConnectEntry
import logging
@@ -8,12 +8,16 @@ logger = logging.getLogger(__name__)
def split_therapy_events(ciqTherapyEvents):
bolusEvents = []
cgmEvents = []
bgEvents = []
for e in ciqTherapyEvents['event']:
event = TConnectEntry.parse_therapy_event(e)
if type(event) == BolusTherapyEvent:
if isinstance(event, BolusTherapyEvent):
bolusEvents.append(event)
elif type(event) == CGMTherapyEvent:
elif isinstance(event, CGMTherapyEvent):
cgmEvents.append(event)
elif isinstance(event, BGTherapyEvent):
bgEvents.append(event)
logger.debug("split_therapy_events: %d bolus, %d CGM" % (len(bolusEvents), len(cgmEvents)))
logger.debug("split_therapy_events: %d bolus, %d CGM, %d BG" % (len(bolusEvents), len(cgmEvents), len(bgEvents)))
# TODO: BG events (CGM Calibration) values are not currently returned from ciq_therapy_events.py
return bolusEvents, cgmEvents
+3 -1
View File
@@ -3,7 +3,7 @@ import sys
import arrow
from tconnectsync.domain.bolus import Bolus
from tconnectsync.domain.therapy_event import BolusTherapyEvent, CGMTherapyEvent
from tconnectsync.domain.therapy_event import BolusTherapyEvent, CGMTherapyEvent, BGTherapyEvent
try:
from ..secret import TIMEZONE_NAME
@@ -200,6 +200,8 @@ class TConnectEntry:
return BolusTherapyEvent.parse(data)
elif data["type"] == "CGM":
return CGMTherapyEvent.parse(data)
elif data["type"] == "BG":
return BGTherapyEvent.parse(data)
raise UnknownTherapyEventException(data)