Compare commits

..
6 Commits
Author SHA1 Message Date
James Woglom 8fb2ced9c5 version: bump to 0.9.6 2023-10-18 00:05:10 -04:00
James WoglomandGitHub d902cd7aab Push latest tag 2023-10-18 00:02:32 -04:00
James WoglomandGitHub a781e458c3 Update README.md 2023-09-30 21:01:15 -04:00
James Woglom 3fe131bcf3 version: bump to 0.9.5 2023-09-30 20:48:39 -04:00
James Woglom 3260442893 Bump supported tconnect software version 2023-09-30 20:37:05 -04:00
James Woglom e3542bc002 webui: detect logged out state and trigger re-login 2023-09-30 20:33:55 -04:00
7 changed files with 80 additions and 6 deletions
+10
View File
@@ -22,6 +22,16 @@ jobs:
repository: jwoglom/tconnectsync/tconnectsync
tag_with_ref: true
- name: Push latest tag to GitHub Packages
uses: docker/build-push-action@v1
with:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
registry: docker.pkg.github.com
repository: jwoglom/tconnectsync/tconnectsync
tags: latest
push: ${{ startsWith(github.ref, 'refs/tags/') }}
push_to_dockerhub:
name: Push Docker image to Docker Hub
runs-on: ubuntu-latest
+3 -1
View File
@@ -35,7 +35,9 @@ jobs:
pipenv check \
--ignore 51499 \
--ignore 52495 \
--ignore 52365
--ignore 52365 \
--ignore 59956 \
--ignore 58755
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
+1 -1
View File
@@ -55,7 +55,7 @@ The following synchronization features can be optionally enabled:
* 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**](https://github.com/jwoglom/tconnectsync/issues/16):
The following synchronization features are considered to be in alpha, and haven't been widely tested. If you want to use them, [set `ENABLE_TESTING_MODES=true` for them to show up](https://github.com/jwoglom/tconnectsync/blob/master/tconnectsync/features.py#L29):
* `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.
+1 -1
View File
@@ -1,6 +1,6 @@
[metadata]
name = tconnectsync
version = 0.9.4
version = 0.9.6
author = James Woglom
author_email = j@wogloms.net
description = Syncs Tandem t:connect pump data to Nightscout for the t:slim X2
+1 -1
View File
@@ -14,7 +14,7 @@ class ControlIQApi:
BASE_URL = 'https://tdcservices.tandemdiabetes.com/'
LOGIN_URL = 'https://tconnect.tandemdiabetes.com/login.aspx?ReturnUrl=%2f'
LAST_CONFIRMED_SOFTWARE_VERSION = 't:connect 7.15.0.1'
LAST_CONFIRMED_SOFTWARE_VERSION = 't:connect 7.16.0.1'
userGuid = None
accessToken = None
+5 -1
View File
@@ -30,10 +30,14 @@ class WebUIScraper:
return self.controliq.needs_relogin()
def _get(self, endpoint):
r = self.controliq.loginSession.get(self.BASE_URL + endpoint, headers=base_headers())
r = self.controliq.loginSession.get(self.BASE_URL + endpoint, headers=base_headers(), allow_redirects=True)
if r.status_code != 200:
raise ApiException(r.status_code, "WebUIScraper HTTP %s response: %s" % (str(r.status_code), r.text))
if 'login.aspx' in r.url:
raise ApiException(401, "WebUIScraper HTTP %s response for login page, returning 401: %s" % (str(r.status_code), r.url))
return r
+59 -1
View File
@@ -18,7 +18,7 @@ from .fake import ControlIQApi
from tconnectsync.api.controliq import ControlIQApi as RealControlIQApi
from tconnectsync.api.common import ApiException, ApiLoginException, base_headers
class TestWebUIScraper(unittest.TestCase):
class TestWebUIScraperMyDevices(unittest.TestCase):
maxDiff = None
DEVICES_HTML = """
@@ -319,6 +319,64 @@ class TestWebUIScraper(unittest.TestCase):
'guid': None
})})
REDIRECT_HTML = """<html><head><title>Object moved</title></head><body>
<h2>Object moved to <a href="/login.aspx?ReturnUrl=%2fmyaccount%2fmy_devices.aspx">here</a>.</h2>
</body></html>"""
LOGIN_HTML = """<html></html>"""
def test_relogin_when_redirected_to_login_page(self):
ciq = ControlIQApi()
ciq.needs_relogin = lambda: False
ciq.loginSession = requests.Session()
ciq.LOGIN_URL = RealControlIQApi.LOGIN_URL
ciq._email = 'EMAIL'
ciq._password = 'PASSWORD'
login_times = []
def fake_login(email, password):
self.assertEqual(email, ciq._email)
self.assertEqual(password, ciq._password)
login_times.append(1)
return True
ciq.login = fake_login
webui = WebUIScraper(ciq)
ciq.login(ciq._email, ciq._password)
self.assertEqual(len(login_times), 1)
with requests_mock.Mocker() as m:
m.get('https://tconnect.tandemdiabetes.com/myaccount/my_devices.aspx',
request_headers=base_headers(),
status_code=302,
headers={'Location': 'https://tconnect.tandemdiabetes.com/login.aspx?ReturnUrl=%2fmyaccount%2fmy_devices.aspx'},
text=self.REDIRECT_HTML)
m.get('https://tconnect.tandemdiabetes.com/login.aspx?ReturnUrl=%2fmyaccount%2fmy_devices.aspx',
request_headers=base_headers(),
status_code=200,
text=self.LOGIN_HTML)
self.assertRaises(ApiException, webui.my_devices)
self.assertEqual(len(login_times), 2)
with requests_mock.Mocker() as m:
m.get('https://tconnect.tandemdiabetes.com/myaccount/my_devices.aspx',
request_headers=base_headers(),
text=self.DEVICES_HTML)
devices = webui.my_devices()
self.assertEqual(len(login_times), 2)
class TestWebUIScraperPumpSettings(unittest.TestCase):
maxDiff = None
PUMP_SETTINGS_HTML = """
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">