-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathgetdata.py
148 lines (117 loc) · 4.24 KB
/
getdata.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
from secret import USERNAME, PASSWORD, NS_URL, NS_SECRET
import requests, json, arrow, hashlib, urllib, datetime
import cloudscraper
DBM_HOST = 'https://analytics.diabetes-m.com'
# this is the enteredBy field saved to Nightscout
NS_AUTHOR = "Diabetes-M (dm2nsc)"
def get_login():
sess = cloudscraper.create_scraper(
browser={
'browser': 'chrome',
'platform': 'windows',
'desktop': True
}
)
index = sess.get(DBM_HOST + '/login')
return sess.post(DBM_HOST + '/api/v1/user/authentication/login', json={
'username': USERNAME,
'password': PASSWORD,
'device': ''
}, headers={
'origin': DBM_HOST,
'referer': DBM_HOST + '/login'
}, cookies=index.cookies), sess
def get_entries(login, sess):
auth_code = login.json()['token']
print("Loading entries...")
entries = sess.post(DBM_HOST + '/api/v1/diary/entries/list',
cookies=login.cookies,
headers={
'origin': DBM_HOST,
'authorization': 'Bearer '+auth_code
}, json={
'fromDate': -1,
'toDate': -1,
'page_count': 90000,
'page_start_entry_time': 0
})
return entries.json()
def to_mgdl(mmol):
return round(mmol*18)
def convert_nightscout(entries, start_time=None):
out = []
for entry in entries:
bolus = entry["carb_bolus"] + entry["correction_bolus"]
time = arrow.get(int(entry["entry_time"])/1000).to(entry["timezone"])
notes = entry["notes"]
if start_time and start_time >= time:
continue
author = NS_AUTHOR
# You can do some custom processing here, if necessary
dat = {
"eventType": "Meal Bolus",
"created_at": time.format(),
"carbs": entry["carbs"],
"insulin": bolus,
"notes": notes,
"enteredBy": author
}
if entry["glucose"]:
bgEvent = {
"eventType": "BG Check",
"glucoseType": "Finger",
}
# entry["glucose"] is always in mmol/L, but entry["glucoseInCurrentUnit"] is either mmol/L or mg/dL depending on account settings
# entry["us_units"] appears to always be false, even if your account is set to mg/dL, so it is ignored for now
unit_mmol = (entry["glucoseInCurrentUnit"] == entry["glucose"])
# for mmol/L units, if no carbs or bolus is present then we upload with mmol/L units
# to nightscout, otherwise we use the converted mg/dL as normal.
# this is due to a UI display issue with Nightscout (it will show mg/dL units always for
# bg-only readings, but convert to the NS default unit otherwise)
if unit_mmol and not (entry["carbs"] or bolus):
bgEvent["units"] = "mmol"
# save the mmol/L value from DB-M
bgEvent["glucose"] = entry["glucose"]
else:
bgEvent["units"] = "mg/dL"
# convert mmol/L -> mg/dL
bgEvent["glucose"] = to_mgdl(entry["glucose"])
dat.update(bgEvent)
if entry["hba1c"]:
dat["eventType"] = "HbA1c"
dat["hba1c"] = entry["hba1c"]
dat["notes"] = "HbA1c %s%s" % (entry["hba1c"], '%')
out.append(dat)
return out
def upload_nightscout(ns_format):
upload = requests.post(NS_URL + 'api/v1/treatments?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 get_last_nightscout():
last = requests.get(NS_URL + 'api/v1/treatments?count=1000&find[enteredBy]='+urllib.parse.quote(NS_AUTHOR))
if last.status_code == 200:
js = last.json()
if len(js) > 0:
return arrow.get(js[0]['created_at']).datetime
def main():
print("Logging in to Diabetes-M...", datetime.datetime.now())
login, sess = get_login()
if login.status_code == 200:
entries = get_entries(login, sess)
else:
print("Error logging in to Diabetes-M: ",login.status_code, login.text)
exit(0)
print("Loaded", len(entries["logEntryList"]), "entries")
# skip uploading entries past the last entry
# uploaded to Nightscout by `NS_AUTHOR`
ns_last = get_last_nightscout()
ns_format = convert_nightscout(entries["logEntryList"], ns_last)
print("Converted", len(ns_format), "entries to Nightscout format")
print(ns_format)
print("Uploading", len(ns_format), "entries to Nightscout...")
upload_nightscout(ns_format)
if __name__ == '__main__':
main()