mirror of
https://github.com/bckelley/tconnectsync.git
synced 2026-08-24 03:34:12 -05:00
nightscout.py: move methods into class, initialize NightscoutApi in main
Changes all code which interacts with the nightscout api to invoke it via a NightscoutApi object which is passed to it and defined in the main, rather than having utility methods in nightscout.py which rely on the global secret file state of nightscout url/secret.
This commit is contained in:
@@ -9,11 +9,14 @@ from tconnectsync.api import TConnectApi
|
||||
from tconnectsync.process import process_time_range
|
||||
from tconnectsync.autoupdate import process_auto_update
|
||||
from tconnectsync.check import check_login
|
||||
from tconnectsync.nightscout import NightscoutApi
|
||||
|
||||
try:
|
||||
from tconnectsync.secret import (
|
||||
TCONNECT_EMAIL,
|
||||
TCONNECT_PASSWORD
|
||||
TCONNECT_PASSWORD,
|
||||
NS_URL,
|
||||
NS_SECRET
|
||||
)
|
||||
except Exception:
|
||||
print('Unable to read secret.py')
|
||||
@@ -49,15 +52,17 @@ def main():
|
||||
|
||||
tconnect = TConnectApi(TCONNECT_EMAIL, TCONNECT_PASSWORD)
|
||||
|
||||
nightscout = NightscoutApi(NS_URL, NS_SECRET)
|
||||
|
||||
if args.check_login:
|
||||
return check_login(tconnect, time_start, time_end)
|
||||
|
||||
if args.auto_update:
|
||||
print("Starting auto-update between", time_start, "and", time_end, "(PRETEND)" if args.pretend else "")
|
||||
process_auto_update(tconnect, time_start, time_end, args.pretend)
|
||||
process_auto_update(tconnect, nightscout, time_start, time_end, args.pretend)
|
||||
else:
|
||||
print("Processing data between", time_start, "and", time_end, "(PRETEND)" if args.pretend else "")
|
||||
added = process_time_range(tconnect, time_start, time_end, args.pretend)
|
||||
added = process_time_range(tconnect, nightscout, time_start, time_end, args.pretend)
|
||||
print("Added", added, "items")
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -12,7 +12,7 @@ from .secret import (
|
||||
Performs the auto-update functionality. Runs indefinitely in a loop
|
||||
until stopped (ctrl+c).
|
||||
"""
|
||||
def process_auto_update(tconnect, time_start, time_end, pretend):
|
||||
def process_auto_update(tconnect, nightscout, time_start, time_end, pretend):
|
||||
# Read from android api, find exact interval to cut down on API calls
|
||||
# Refresh API token. If failure, die, have wrapper script re-run.
|
||||
|
||||
@@ -28,7 +28,7 @@ def process_auto_update(tconnect, time_start, time_end, pretend):
|
||||
if pretend:
|
||||
print('Would update now')
|
||||
else:
|
||||
added = process_time_range(tconnect, time_start, time_end, pretend)
|
||||
added = process_time_range(tconnect, nightscout, time_start, time_end, pretend)
|
||||
print('Added', added, 'items')
|
||||
|
||||
if last_event_index:
|
||||
|
||||
+10
-5
@@ -1,7 +1,4 @@
|
||||
from .nightscout import api_status
|
||||
|
||||
from .secret import PUMP_SERIAL_NUMBER
|
||||
|
||||
from .nightscout import NightscoutApi
|
||||
|
||||
"""
|
||||
Attempts to authenticate with each t:connect API,
|
||||
@@ -32,16 +29,24 @@ def check_login(tconnect, time_start, time_end):
|
||||
summary = tconnect.android.user_profile()
|
||||
print("Android user profile: %s" % summary)
|
||||
|
||||
from .secret import PUMP_SERIAL_NUMBER
|
||||
|
||||
event = tconnect.android.last_event_uploaded(PUMP_SERIAL_NUMBER)
|
||||
print("\nAndroid last uploaded event: %s" % event)
|
||||
except ImportError:
|
||||
print("Error: Unable to load config file.")
|
||||
except Exception as e:
|
||||
print("Error occurred querying Android API: %s" % e)
|
||||
errors += 1
|
||||
|
||||
print("\nLogging in to Nightscout...")
|
||||
try:
|
||||
status = api_status()
|
||||
from .secret import NS_URL, NS_SECRET
|
||||
|
||||
status = NightscoutApi(NS_URL, NS_SECRET).api_status()
|
||||
print("\nNightscout status: %s" % status)
|
||||
except ImportError:
|
||||
print("Error: Unable to load config file.")
|
||||
except Exception as e:
|
||||
print("Error occurred querying Nightscout API: %s" % e)
|
||||
errors += 1
|
||||
|
||||
+67
-52
@@ -6,64 +6,79 @@ import urllib.parse
|
||||
|
||||
from urllib.parse import urljoin
|
||||
|
||||
from .api.common import ApiException
|
||||
from .parser.nightscout import ENTERED_BY
|
||||
|
||||
try:
|
||||
from .secret import NS_URL, NS_SECRET, TIMEZONE_NAME
|
||||
except Exception:
|
||||
print('Unable to import Nightscout secrets from secret.py')
|
||||
sys.exit(1)
|
||||
# try:
|
||||
# from .secret import NS_URL, NS_SECRET
|
||||
# except Exception:
|
||||
# print('Unable to import Nightscout secrets from secret.py')
|
||||
# sys.exit(1)
|
||||
|
||||
class NightscoutApi:
|
||||
def __init__(self, url, secret):
|
||||
self.url = url
|
||||
self.secret = secret
|
||||
|
||||
|
||||
def upload_nightscout(ns_format, entity='treatments'):
|
||||
upload = requests.post(urljoin(NS_URL, 'api/v1/' + entity + '?api_secret=' + NS_SECRET), json=ns_format, headers={
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'api-secret': hashlib.sha1(NS_SECRET.encode()).hexdigest()
|
||||
})
|
||||
print("Nightscout upload status:", upload.status_code, upload.text)
|
||||
def upload_entry(self, ns_format, entity='treatments'):
|
||||
r = requests.post(urljoin(self.url, 'api/v1/' + entity + '?api_secret=' + self.secret), json=ns_format, headers={
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'api-secret': hashlib.sha1(self.secret.encode()).hexdigest()
|
||||
})
|
||||
if r.status_code != 200:
|
||||
raise ApiException(r.status_code, "Nightscout upload response: %s" % r.text)
|
||||
|
||||
def delete_nightscout(entity):
|
||||
upload = requests.delete(urljoin(NS_URL, 'api/v1/' + entity + '?api_secret=' + NS_SECRET), json={}, headers={
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'api-secret': hashlib.sha1(NS_SECRET.encode()).hexdigest()
|
||||
})
|
||||
print("Nightscout delete status:", upload.status_code, upload.text)
|
||||
def delete_entry(self, entity):
|
||||
r = requests.delete(urljoin(self.url, 'api/v1/' + entity + '?api_secret=' + self.secret), json={}, headers={
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'api-secret': hashlib.sha1(self.secret.encode()).hexdigest()
|
||||
})
|
||||
if r.status_code != 200:
|
||||
raise ApiException(r.status_code, "Nightscout delete response: %s" % r.text)
|
||||
|
||||
def put_nightscout(ns_format, entity):
|
||||
upload = requests.put(urljoin(NS_URL, 'api/v1/' + entity + '?api_secret=' + NS_SECRET), json=ns_format, headers={
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'api-secret': hashlib.sha1(NS_SECRET.encode()).hexdigest()
|
||||
})
|
||||
print("Nightscout put status:", upload.status_code, upload.text)
|
||||
def put_entry(self, ns_format, entity):
|
||||
r = requests.put(urljoin(self.url, 'api/v1/' + entity + '?api_secret=' + self.secret), json=ns_format, headers={
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'api-secret': hashlib.sha1(self.secret.encode()).hexdigest()
|
||||
})
|
||||
if r.status_code != 200:
|
||||
raise ApiException(r.status_code, "Nightscout put response: %s" % r.text)
|
||||
|
||||
def last_uploaded_nightscout_entry(eventType):
|
||||
latest = requests.get(urljoin(NS_URL, 'api/v1/treatments?count=1&find[enteredBy]=' + urllib.parse.quote(ENTERED_BY) + '&find[eventType]=' + urllib.parse.quote(eventType) + '&ts=' + str(time.time())), headers={
|
||||
'api-secret': hashlib.sha1(NS_SECRET.encode()).hexdigest()
|
||||
})
|
||||
j = latest.json()
|
||||
if j and len(j) > 0:
|
||||
return j[0]
|
||||
return None
|
||||
def last_uploaded_entry(self, eventType):
|
||||
latest = requests.get(urljoin(self.url, 'api/v1/treatments?count=1&find[enteredBy]=' + urllib.parse.quote(ENTERED_BY) + '&find[eventType]=' + urllib.parse.quote(eventType) + '&ts=' + str(time.time())), headers={
|
||||
'api-secret': hashlib.sha1(self.secret.encode()).hexdigest()
|
||||
})
|
||||
if latest.status_code != 200:
|
||||
raise ApiException(latest.status_code, "Nightscout treatments response: %s" % latest.text)
|
||||
|
||||
def last_uploaded_nightscout_activity(activityType):
|
||||
latest = requests.get(urljoin(NS_URL, 'api/v1/activity?find[enteredBy]=' + urllib.parse.quote(ENTERED_BY) + '&find[activityType]=' + urllib.parse.quote(activityType) + '&ts=' + str(time.time())), headers={
|
||||
'api-secret': hashlib.sha1(NS_SECRET.encode()).hexdigest()
|
||||
})
|
||||
j = latest.json()
|
||||
if j and len(j) > 0:
|
||||
return j[0]
|
||||
return None
|
||||
j = latest.json()
|
||||
if j and len(j) > 0:
|
||||
return j[0]
|
||||
return None
|
||||
|
||||
"""
|
||||
Returns general status information about the Nightscout server.
|
||||
"""
|
||||
def api_status():
|
||||
status = requests.get(urljoin(NS_URL, 'api/v1/status.json'), headers={
|
||||
'api-secret': hashlib.sha1(NS_SECRET.encode()).hexdigest()
|
||||
})
|
||||
if status.status_code != 200:
|
||||
raise Exception('HTTP error status code (%d) from Nightscout: %s' % (status.status_code, status.text))
|
||||
return status.json()
|
||||
def last_uploaded_activity(self, activityType):
|
||||
latest = requests.get(urljoin(self.url, 'api/v1/activity?find[enteredBy]=' + urllib.parse.quote(ENTERED_BY) + '&find[activityType]=' + urllib.parse.quote(activityType) + '&ts=' + str(time.time())), headers={
|
||||
'api-secret': hashlib.sha1(self.secret.encode()).hexdigest()
|
||||
})
|
||||
if latest.status_code != 200:
|
||||
raise ApiException(latest.status_code, "Nightscout activity response: %s" % latest.text)
|
||||
|
||||
j = latest.json()
|
||||
if j and len(j) > 0:
|
||||
return j[0]
|
||||
return None
|
||||
|
||||
"""
|
||||
Returns general status information about the Nightscout server.
|
||||
"""
|
||||
def api_status(self):
|
||||
status = requests.get(urljoin(self.url, 'api/v1/status.json'), headers={
|
||||
'api-secret': hashlib.sha1(self.secret.encode()).hexdigest()
|
||||
})
|
||||
if status.status_code != 200:
|
||||
raise Exception('HTTP error status code (%d) from Nightscout: %s' % (status.status_code, status.text))
|
||||
return status.json()
|
||||
@@ -20,7 +20,7 @@ Given a TConnectApi object and start/end range, performs a single
|
||||
cycle of synchronizing data within the time range.
|
||||
If pretend is true, then doesn't actually write data to Nightscout.
|
||||
"""
|
||||
def process_time_range(tconnect, time_start, time_end, pretend):
|
||||
def process_time_range(tconnect, nightscout, time_start, time_end, pretend):
|
||||
print("Downloading t:connect ControlIQ data")
|
||||
try:
|
||||
ciqTherapyTimelineData = tconnect.controliq.therapy_timeline(time_start, time_end)
|
||||
@@ -51,13 +51,12 @@ def process_time_range(tconnect, time_start, time_end, pretend):
|
||||
if csvBasalData:
|
||||
add_csv_basal_events(basalEvents, csvBasalData)
|
||||
|
||||
added += ns_write_basal_events(basalEvents, pretend=pretend)
|
||||
|
||||
added += ns_write_basal_events(nightscout, basalEvents, pretend=pretend)
|
||||
|
||||
bolusEvents = process_bolus_events(bolusData)
|
||||
added += ns_write_bolus_events(bolusEvents, pretend=pretend)
|
||||
added += ns_write_bolus_events(nightscout, bolusEvents, pretend=pretend)
|
||||
|
||||
iobEvents = process_iob_events(iobData)
|
||||
added += ns_write_iob_events(iobEvents, pretend=pretend)
|
||||
added += ns_write_iob_events(nightscout, iobEvents, pretend=pretend)
|
||||
|
||||
return added
|
||||
@@ -4,11 +4,6 @@ from ..parser.nightscout import (
|
||||
BASAL_EVENTTYPE,
|
||||
NightscoutEntry
|
||||
)
|
||||
from ..nightscout import (
|
||||
last_uploaded_nightscout_entry,
|
||||
put_nightscout,
|
||||
upload_nightscout
|
||||
)
|
||||
from ..parser.tconnect import TConnectEntry
|
||||
|
||||
|
||||
@@ -64,8 +59,8 @@ def add_csv_basal_events(basalEvents, data):
|
||||
"""
|
||||
Given processed basal data, adds basal events to Nightscout.
|
||||
"""
|
||||
def ns_write_basal_events(basalEvents, pretend=False):
|
||||
last_upload = last_uploaded_nightscout_entry(BASAL_EVENTTYPE)
|
||||
def ns_write_basal_events(nightscout, basalEvents, pretend=False):
|
||||
last_upload = nightscout.last_uploaded_entry(BASAL_EVENTTYPE)
|
||||
last_upload_time = None
|
||||
if last_upload:
|
||||
last_upload_time = arrow.get(last_upload["created_at"])
|
||||
@@ -102,8 +97,8 @@ def ns_write_basal_events(basalEvents, pretend=False):
|
||||
print("Replacing last uploaded entry:", last_upload)
|
||||
if not pretend:
|
||||
entry['_id'] = last_upload['_id']
|
||||
put_nightscout(entry, entity='treatments')
|
||||
nightscout.put_entry(entry, entity='treatments')
|
||||
elif not pretend:
|
||||
upload_nightscout(entry)
|
||||
nightscout.upload_entry(entry)
|
||||
|
||||
return add_count
|
||||
|
||||
@@ -4,11 +4,6 @@ from ..parser.nightscout import (
|
||||
BOLUS_EVENTTYPE,
|
||||
NightscoutEntry
|
||||
)
|
||||
from ..nightscout import (
|
||||
last_uploaded_nightscout_entry,
|
||||
put_nightscout,
|
||||
upload_nightscout
|
||||
)
|
||||
from ..parser.tconnect import TConnectEntry
|
||||
|
||||
"""
|
||||
@@ -35,8 +30,8 @@ def process_bolus_events(bolusdata):
|
||||
"""
|
||||
Given processed bolus data, adds bolus events to Nightscout.
|
||||
"""
|
||||
def ns_write_bolus_events(bolusEvents, pretend=False):
|
||||
last_upload = last_uploaded_nightscout_entry(BOLUS_EVENTTYPE)
|
||||
def ns_write_bolus_events(nightscout, bolusEvents, pretend=False):
|
||||
last_upload = nightscout.last_uploaded_entry(BOLUS_EVENTTYPE)
|
||||
last_upload_time = None
|
||||
if last_upload:
|
||||
last_upload_time = arrow.get(last_upload["created_at"])
|
||||
@@ -60,6 +55,6 @@ def ns_write_bolus_events(bolusEvents, pretend=False):
|
||||
|
||||
print(" Processing bolus:", event, "entry:", entry)
|
||||
if not pretend:
|
||||
upload_nightscout(entry)
|
||||
nightscout.upload_entry(entry)
|
||||
|
||||
return add_count
|
||||
|
||||
@@ -4,11 +4,6 @@ from ..parser.nightscout import (
|
||||
IOB_ACTIVITYTYPE,
|
||||
NightscoutEntry
|
||||
)
|
||||
from ..nightscout import (
|
||||
last_uploaded_nightscout_activity,
|
||||
delete_nightscout,
|
||||
upload_nightscout
|
||||
)
|
||||
from ..parser.tconnect import TConnectEntry
|
||||
|
||||
"""
|
||||
@@ -26,8 +21,8 @@ def process_iob_events(iobdata):
|
||||
"""
|
||||
Given processed IOB data, creates a single Nightscout activity definition to store IOB.
|
||||
"""
|
||||
def ns_write_iob_events(iobEvents, pretend=False):
|
||||
last_upload = last_uploaded_nightscout_activity(IOB_ACTIVITYTYPE)
|
||||
def ns_write_iob_events(nightscout, iobEvents, pretend=False):
|
||||
last_upload = nightscout.last_uploaded_activity(IOB_ACTIVITYTYPE)
|
||||
last_upload_time = None
|
||||
if last_upload:
|
||||
last_upload_time = arrow.get(last_upload["created_at"])
|
||||
@@ -49,12 +44,12 @@ def ns_write_iob_events(iobEvents, pretend=False):
|
||||
|
||||
print(" Processing iob:", event, "entry:", entry)
|
||||
if not pretend:
|
||||
upload_nightscout(entry, entity='activity')
|
||||
nightscout.upload_entry(entry, entity='activity')
|
||||
|
||||
# Delete the previous activity
|
||||
if last_upload and '_id' in last_upload:
|
||||
print(" Deleting old iob entry:", last_upload)
|
||||
if not pretend:
|
||||
delete_nightscout('activity/{}'.format(last_upload['_id']))
|
||||
nightscout.delete_entry('activity/{}'.format(last_upload['_id']))
|
||||
|
||||
return 1
|
||||
Reference in New Issue
Block a user