Package: tconnectsync
tconnectsyncTconnectsync synchronizes data one-way from the Tandem Diabetes t:connect web/mobile application to Nightscout.If you have a t:slim X2 pump with the companion t:connect mobile Android or iOS app, this will allow your pump bolus and basal data to be uploaded toNightscoutautomatically.
Together with a CGM uploader, such asxDrip+or the official Dexcom mobile app plus Dexcom Share, this allows your CGMandpump data to be automatically uploaded to Nightscout!If you have an Android phone, you can usetconnectpatcherto modify the t:connect Android app to upload more frequently. By default, pump data is uploaded to Tandem's servers every hour, but with tconnectpatcher the frequency can be brought down toas low as every five minutes! This allows for nearly real-time (albeit not fully instantaneous) pump data updates, almost like your pump uploads data directly to Nightscout!How It WorksAt a high level, tconnectsync works by querying Tandem's undocumented APIs to receive basal and bolus data from t:connect, and then uploads that data as treatment objects to Nightscout. It contains features for checking for new Tandem pump data continuously, and updating that data along with the pump's reported IOB value to Nightscout whenever there is new data.When you run the program with no arguments, it performs a single cycle of the following, and exits after completion:Queries for basal information via the t:connect ControlIQ API.Queries for bolus, basal, and IOB data via the t:connect non-ControlIQ API.Merges the basal information received from the two APIs. (If using ControlIQ, then basal information appears only on the ControlIQ API. If not using ControlIQ, it appears only on the legacy API.)Queries Nightscout for the most recently created Temp Basal object by tconnectsync, and uploads all data newer than that.Queries Nightscout for the most recently created Bolus object by tconnectsync, and uploads all data newer than that.If run with the--auto-updateflag, then the application performs the following steps:Queries an API endpoint used only by the t:connect mobile app which returns an internal event ID, corresponding to the most recent event published by the mobile app.Whenever the internal event ID changes (denoting that the mobile app uploaded new data to synchronize), perform all of the above mentioned steps to synchronize data.What Gets SyncedTconnectsync is composed of individual so-calledsynchronization features, which are elements of data that can be
synchronized between t:connect data from the pump and Nightscout.
When setting up tconnectsync, you can choose to configure which synchronization features are enabled and disabled.Here are a few examples of reasons why you might want to adjust the enabled synchronization features:If you currently input boluses into Nightscout manually with comments, then you may wish todisable theBOLUSsynchronization featureso that there are no duplicated boluses in Nightscout.If you want to see Sleep and Exercise Mode data appear in Nightscout, then you may with toenable thePUMP_EVENTSsynchronization feature.If you want to automatically update your Nightscout insulin profile settings from your pump, then you may want toenable thePROFILESsynchronization feature.These synchronization features are enabled by default:BASAL: Basal dataBOLUS: Bolus dataThe following synchronization features can be optionally enabled:PROFILES: Insulin profile information, including segments, basal rates, correction factors, carb ratios, and the profile which is active.PUMP_EVENTS: Events reported by the pump. Includes support for the following:Site/Cartridge Change (occurs for both a site change and a cartridge change)Empty Cartridge/Pump Shutdown (from my investigation, occurs either when the cartridge runs out of insulin OR you hard-shut off the pump)User Suspended (occurs when you manually disable insulin delivery)Exercise Mode (in Nightscout, appears with a start and end time)Sleep Mode (in Nightscout, appears with a start and end time)IOB: Insulin-on-board data. Only the most recent IOB entry is saved to Nightscout, as an "activity". The Nightscout UI does not currently display this information. In order to read this value, you need to query the Nightscout activity API endpoint. If you don't know what that means, then there is no reason to enable this option.The following synchronization features are under development,but are not yet ready for use:BOLUS_BG: Adds BG readings which are associated with boluses on the pump into the Nightscout treatment object. It will determine whether the BG reading was automatically filled via the Dexcom connection on the pump or was manually entered by seeing if the BG reading matches the current CGM reading as known to the pump at that time. Support for this is nearly complete.CGM: Adds Dexcom CGM readings from the pump to Nightscout as SGV (sensor glucose value) entries. This should only be used in a situation where xDrip/Dexcom Share/etc. is not used and the pump connection to the CGM will be the only source of CGM data to Nightscout. This requires additional testing before it should be considered ready.To specify custom synchronization features, pass the names of the desired features to the--featuresflag, e.g.:$tconnectsync--featuresBASALBOLUSPUMP_EVENTSPROFILESIf you're using tconnectsync-heroku, seethis section in its README.SetupThe following setup instructions assume that you have a Linux, MacOS, or Windows (with WSL) machine that will run the application continuously.If you've configured Nightscout before, you may be familiar with Heroku.You can opt to run tconnectsync with Heroku by following these instructions.To get started,you need to choose whether to install the application on your computer viaPip,Pipenv, orDocker.After that, you can choose to run the program continuously viaSupervisordor on a regular interval withCron.NOTE:If you fork the tconnectsync repository on GitHub,do not commit your .env file.
If pushed to GitHub, this will make your tconnect and Nightscout passwords publicly visible and put your data at risk.InstallationFirst, you need to create a file containing configuration values.
The name of this file will be.env, and its location will be dependent on which
method of installation you choose.
You should specify the following parameters:# Your credentials for t:connectTCONNECT_EMAIL='email@email.com'TCONNECT_PASSWORD='password'# Your pump's serial number (numeric)PUMP_SERIAL_NUMBER=11111111# URL of your Nightscout siteNS_URL='https://yournightscouturl/'# Your Nightscout API_SECRET valueNS_SECRET='apisecret'# Current timezone of the pumpTIMEZONE_NAME='America/New_York'This file contains your t:connect username and password, Tandem pump serial number (which is utilized in API calls to t:connect), your Nightscout URL and secret token (for uploading data to Nightscout), and local timezone (the timezone used in t:connect). When specifying the timezone, enter aTZ database name value.(Alternatively, these values can be specified via environment variables.)Installation via PipThis is the easiest method to install.First, ensure that you havePython 3withPipinstalled:On MacOS:Open Terminal. InstallHomebrew, and then runbrew install python3On Linux:Follow your distribution's specific instructions.For Debian/Ubuntu based distros,sudo apt install python3 python3-pipFor CentOS/Rocky Linux 8:sudo dnf install python39-pipsudo alternatives --set python /usr/bin/python3.9On Windows:With WSL:Install Ubuntu under theWindows Subsystem for Linux.
Open the Ubuntu Terminal, then runsudo apt install python3 python3-pip.
Perform the remainder of the steps under the Ubuntu environment.Native:Alternatively, you can run tconnectsync in native Windows with no modifications. However, this is less well-tested (open a GitHub issue if you experience any problems).Now install thetconnectsyncpackage with pip:$ pip3 install tconnectsyncTo install into a user environment instead of system-wide for a more contained install:$ pip3 install --user tconnectsyncThis will place the tconnectsync binary file at/home/<username>/.local/bin/tconnectsyncFor non-WSL Windows, it will be in<PYTHON DIRECTORY>\Lib\site-packages\tconnectsyncIf the pip3 command is not found, runpython3 -m pip install tconnectsyncinstead.After this, you should be able to view tconnectsync's help with:$ tconnectsync --help
usage: tconnectsync [-h] [--version] [--pretend] [-v] [--start-date START_DATE] [--end-date END_DATE] [--days DAYS] [--auto-update] [--check-login]
               [--features {BASAL,BOLUS,IOB,PUMP_EVENTS} [{BASAL,BOLUS,IOB,PUMP_EVENTS} ...]]

Syncs bolus, basal, and IOB data from Tandem Diabetes t:connect to Nightscout.

optional arguments:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  --pretend             Pretend mode: do not upload any data to Nightscout.
  -v, --verbose         Verbose mode: show extra logging details
  --start-date START_DATE
                        The oldest date to process data from. Must be specified with --end-date.
  --end-date END_DATE   The newest date to process data until (inclusive). Must be specified with --start-date.
  --days DAYS           The number of days of t:connect data to read in. Cannot be used with --from-date and --until-date.
  --auto-update         If set, continuously checks for updates from t:connect and syncs with Nightscout.
  --check-login         If set, checks that the provided t:connect credentials can be used to log in.
  --features {BASAL,BOLUS,IOB,PUMP_EVENTS} [{BASAL,BOLUS,IOB,PUMP_EVENTS} ...]
                        Specifies what data should be synchronized between tconnect and Nightscout.Move the.envfile you created to the following folder:MacOS:/Users/<username>/.config/tconnectsync/.envLinux:$HOME/.config/tconnectsync/.envWindows:$HOME/.config/tconnectsync/.env(inside WSL) ORC:\Users\<username>\.config\tconnectsync(native Windows)$ tconnectsync --check-loginIf you receive no errors, then you can move on to theRunning Tconnectsync Continuouslysection.Installing with PipenvYou can run the application using Pipenv.First, ensure you have Python 3 and pip installed, then install pipenv withpip3 install pipenv.Clone the Git repository for tconnectsync and cd into it with:$ git clone https://github.com/jwoglom/tconnectsync
$ cd tconnectsyncThen install tconnectsync's dependencies withpipenv install.
Afterwards, you can launch the program withpipenv run tconnectsyncso long as
you are inside the checked-out tconnectsync folder.$gitclonehttps://github.com/jwoglom/tconnectsync&&cdtconnectsync
$pip3installpipenv
$pipenvinstall
$pipenvruntconnectsync--help
usage:main.py[-h][--version][--pretend][-v][--start-dateSTART_DATE][--end-dateEND_DATE][--daysDAYS][--auto-update][--check-login][--features{BASAL,BOLUS,IOB,PUMP_EVENTS}[{BASAL,BOLUS,IOB,PUMP_EVENTS}...]]Syncsbolus,basal,andIOBdatafromTandemDiabetest:connecttoNightscout.

optionalarguments:-h,--helpshowthishelpmessageandexit--versionshowprogram'sversionnumberandexit--pretendPretendmode:donotuploadanydatatoNightscout.-v,--verboseVerbosemode:showextraloggingdetails--start-dateSTART_DATETheoldestdatetoprocessdatafrom.Mustbespecifiedwith--end-date.--end-dateEND_DATEThenewestdatetoprocessdatauntil(inclusive).Mustbespecifiedwith--start-date.--daysDAYSThenumberofdaysoft:connectdatatoreadin.Cannotbeusedwith--from-dateand--until-date.--auto-updateIfset,continuouslychecksforupdatesfromt:connectandsyncswithNightscout.--check-loginIfset,checksthattheprovidedt:connectcredentialscanbeusedtologin.--features{BASAL,BOLUS,IOB,PUMP_EVENTS}[{BASAL,BOLUS,IOB,PUMP_EVENTS}...]SpecifieswhatdatashouldbesynchronizedbetweentconnectandNightscout.Move the.envfile you created earlier into thetconnectsyncfolder, and run:$ pipenv run tconnectsync --check-loginIf you receive no errors, then you can move on to theRunning Tconnectsync Continuouslysection.Installing with DockerFirst,ensure that you have Docker running and installed.To download and run the prebuilt Docker image from GitHub Packages:$dockerpullghcr.io/jwoglom/tconnectsync/tconnectsync:latest
$dockerrunghcr.io/jwoglom/tconnectsync/tconnectsync--helpMove the.envfile you created earlier into the current folder, and run:$ docker run tconnectsync --check-loginIf you receive no errors, then you can move on to theRunning Tconnectsync Continuouslysection.Building LocallyTo instead build the image locally and launch the project:$gitclonehttps://github.com/jwoglom/tconnectsync
$cdtconnectsync
$dockerbuild-ttconnectsync.
$dockerruntconnectsync--helpMove the.envfile you created earlier into this folder, and run:$ docker run --env-file=.env tconnectsync --check-loginNOTE:If using the--env-fileoption todocker run, you may need to remove all quotation marks ('and"s) around values in the.envfile for Docker to propagate the variables correctly.If you receive no errors, then you can move on to theRunning Tconnectsync Continuouslysection.Running Tconnectsync ContinuouslyYou most likely want tconnectsync to run either continuously (via the auto-update
feature) or on a regular interval (via cron).The supervisord approach is recommended for simplicity.Running with Supervisord (recommended)To configure tconnectsync to run continuously in the background using its--auto-updatefeature, you can use a tool such as Supervisord.First, install supervisord via your Linux system's package manager.
(For example, for Ubuntu/Debian-based systems, runsudo apt install supervisor)Supervisord is configured by creating a configuration file in/etc/supervisor/conf.d.Here is an exampletconnectsync.confwhich you can place in that folder:[program:tconnectsync]
command=/path/to/tconnectsync/run.sh
directory=/path/to/tconnectsync/
stderr_logfile=/path/to/tconnectsync/stderr.log
stdout_logfile=/path/to/tconnectsync/stdout.log
user=<your username>
numprocs=1
autostart=true
autorestart=trueIn order to create arun.shfile, see the section below which aligns with your
choice of installation method.After the configuration file has been created, ensure that Supervisor is running
and configured to start on boot:$sudosystemctldaemon-reload
$sudosystemctlstartsupervisord
$sudosystemctlenablesupervisordThen use thesupervisorctlcommand to manage the status of the tconnectsync program:$sudosupervisorctlstatus
tconnectsyncSTOPPED
$sudosupervisorctlstarttconnectsync
$sudosupervisorctlstatus
tconnectsyncRUNNINGpid18810,uptime00:00:05You can look at thestderr.logandstdout.logfiles to check that tconnectsync
is running and has started up properly:$tail-f/path/to/tconnectsync/stdout.log
Startingauto-updatebetween2021-09-3000:06:39.942273and2021-10-0100:06:39.9422732021-10-0100:06:39DEBUGInstantiatingnewAndroidApi2021-10-0100:06:39DEBUGStartingnewHTTPSconnection(1):tdcservices.tandemdiabetes.com:4432021-10-0100:06:40DEBUGhttps://tdcservices.tandemdiabetes.com:443"POST /cloud/oauth2/token HTTP/1.1"2004042021-10-0100:06:40INFOLoggedintoAndroidApisuccessfully(expiration:2021-10-01T08:06:40.362Z,in7hours,59minutes)With Pip InstallationIn thetconnectsync.conf, you should set/path/to/tconnectsyncto the folder
containing your.envfile.Create arun.shfile containing:#!/bin/bashtconnectsync--auto-updateWith Pipenv InstallationIn thetconnectsync.conf, you should set/path/to/tconnectsyncto the folder
where you checked-out the GitHub repository.An examplerun.shwhich launches tconnectsync within its pipenv-configured virtual environment:#!/bin/bashPIPENV=/home/$(whoami)/.local/bin/pipenvVENV=$($PIPENV--venv)source$VENV/bin/activatecd/path/to/tconnectsyncexecpython3-umain.py--auto-updateWith Docker InstallationIn thetconnectsync.conf, you should set/path/to/tconnectsyncto the folder
where you checked-out the GitHub repository.An examplerun.shif you installed tconnectsync via the GitHub Docker Registry:#!/bin/bashdockerrunghcr.io/jwoglom/tconnectsync/tconnectsync--auto-updateAn examplerun.shif you built tconnectsync locally:#!/bin/bashdockerruntconnectsync--auto-updateRunning with CronIf you choose not to run tconnectsync with--auto-updatecontinuously,
you can instead run it at a periodic interval (i.e. every 15 minutes) by just
invoking tconnectsync with no arguments via cron.If using Pipenv or a virtualenv, make sure that you either prefix the call to main.py withpipenv runor source thebin/activatefile 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 system-wide example configuration in/etc/crontabwhich runs every 15 minutes, on the 15 minute mark:# m         h  dom mon dow user   command0,15,30,45****root/path/to/tconnectsync/run.shAn example of a user crontabcrontab -eif not running system-wide, which runs every 15 minutes:*/15 * * * * /path/to/tconnectsync/run.shYou can use one of the samerun.shfiles referenced above, but remove the--auto-updateflag since you are handling the functionality for running the script periodically yourself.For Native WindowsCreate a batch file 'tconnectsync.bat' file containing:python "C:\Users\<USERNAME>\AppData\Local\Programs\Python\<PYTHONVERSIONDIRECTORY>\Lib\site-packages\tconnectsync\main.py" --auto-updateIfpythondoes not exist in your path, specify the full path topython.exe.If main.py doesn't exist inC:\Users\<USERNAME>\AppData\Local\Programs\Python\<PYTHONVERSIONDIRECTORY>\Lib\site-packages\tconnectsync\, create it to match the copy in this repository.Use Windows Task Schedulerto run this batch file on a scheduled basis.Tandem APIsThis application utilizes three separate Tandem APIs for obtaining t:connect data, referenced here by the identifying part of their URLs:controliq- Contains Control:IQ related data, namely a timeline of all Basal events uploaded by the pump, separated by type (temp basals, algorithmically-updated basals, or profile-updated basals). Additionally includes CGM and Bolus data.android- Used internally by the t:connect Android app, these API endpoints were discovered by reverse-engineering the Android app. Most of the API endpoints are used for uploading pump data, and tconnectsync uses one endpoint which returns the most recent event ID uploaded by the pump, so we know when more data has been uploaded.tconnectws2- More legacy than the others, this seems to power the bulk of the main t:connect website. It is used as a last resort due to severe performance issues with this API (seehttps://github.com/jwoglom/tconnectsync/issues/43). We can use it to retrieve a CSV export of non-ControlIQ basal data, as well as bolus and IOB data. It is only used for bolus data as a fallback, and for pump-reported IOB data if requested. Full tracking of pump events also uses a limited version of this API.I have only tested tconnectsync with a Tandem pump set in the US Eastern timezone. Tandem's (to us, undocumented) APIs area bit loose with timezones, so please let me know if you notice any timezone-related bugs.Backfilling t:connect DataTo backfill existing t:connect data in to Nightscout, you can use the--start-dateand--end-dateoptions. For example, the following will upload all t:connect data between January 1st and March 1st, 2020 to Nightscout:python3 main.py --start-date 2020-01-01 --end-date 2020-03-01In order to bulk-import a lot of data, you may need to use shorter intervals, and invoke tconnectsync multiple times. Tandem's API endpoints occasionally return invalid data if you request too large of a data window which causes tconnectsync to error out mid-way through.One oddity when backfilling data is that the Control:IQ specific API endpoints return errors if they are queried before you updated your pump to utilize Control:IQ. This ispartially worked around in tconnectsync's code, but you might need to update the logic if you did not switch to a Control:IQ enabled pump immediately after launch.t:connect API TestingTo test t:connect API endpoints in a Python shell, you can do something like the following:importtconnectsynctconnectsync.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')