Compare commits

...
11 Commits
Author SHA1 Message Date
James Woglom ea84b0b9cc v2.2.2 2024-12-30 22:05:22 -05:00
James Woglom 07aaea9e1c fix tests 2024-12-30 22:05:11 -05:00
James Woglom 67b9f42f9b v2.2.1 2024-12-30 22:02:54 -05:00
James Woglom 997ab7bac8 attempt to fix batteryChargePercent 2024-12-30 22:02:36 -05:00
James Woglom b1f8263ceb v2.2.0 2024-12-13 19:47:29 -05:00
James Woglom 29d08a7f1b fix non-autoupdate 2024-12-13 19:47:01 -05:00
James Woglom c7ade49eea devicestatus: tune nightscout output to look more like Loops uploader 2024-12-13 02:09:36 -05:00
James Woglom 1f0fbd7788 less noisy logs in update profiles 2024-12-13 01:42:58 -05:00
James Woglom 4bda0a21f2 more explicit logging for last update seen 2024-12-13 01:41:16 -05:00
James Woglom d1341e09c0 devicestatus: set pump.battery.percent 2024-12-12 22:20:13 -05:00
James Woglom fb9588ff2c catch iso8601 date errors 2024-12-12 00:41:51 -05:00
10 changed files with 41 additions and 16 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
[metadata]
name = tconnectsync
version = 2.1.9
version = 2.2.2
author = James Woglom
author_email = j@wogloms.net
description = Syncs Tandem Source (formerly t:connect) insulin pump data to Nightscout for the t:slim X2
+1 -1
View File
@@ -120,7 +120,7 @@ def main(*args, **kwargs):
sys.exit(u.process(tconnect, nightscout, time_start, time_end, args.pretend, features=args.features))
else:
tconnectDevice = TandemSourceChooseDevice(secret, tconnect).choose()
added, last_event_id = TandemSourceProcessTimeRange(tconnect, nightscout, tconnectDevice, pretend=args.pretend, features=args.features).process(time_start, time_end)
added, last_event_id = TandemSourceProcessTimeRange(tconnect, nightscout, tconnectDevice, pretend=args.pretend, secret=secret, features=args.features).process(time_start, time_end)
# return exit code 0 if processed events
sys.exit(0 if added>0 else 1)
+1 -1
View File
@@ -4495,7 +4495,7 @@ class LidDailyBasal(BaseEvent):
@property
def batteryChargePercent(self):
return (256*(self.batterychargepercentmsbRaw%2)+self.batterychargepercentlsbRaw)/512
return (256*(self.batterychargepercentmsbRaw-14)+self.batterychargepercentlsbRaw)/(3*256)
@staticmethod
def build(raw):
+1 -1
View File
@@ -116,7 +116,7 @@ def transform_battery_charge_percent(event_def, name, name_fmt, field, tx):
out += [
'@property',
f'def batteryChargePercent(self):',
f' return (256*(self.batterychargepercentmsbRaw%2)+self.batterychargepercentlsbRaw)/512',
f' return (256*(self.batterychargepercentmsbRaw-14)+self.batterychargepercentlsbRaw)/(3*256)',
''
]
+12
View File
@@ -71,6 +71,9 @@ class NightscoutApi:
'api-secret': hashlib.sha1(self.secret.encode()).hexdigest()
}, verify=self.verify)
if latest.status_code != 200:
if 'as a valid ISO-8601 date' in latest.text:
logger.warning("Nightscout last_uploaded_entry %s could not process ISO-8601 date: start=%s end=%s dateFilter=%s" % (eventType, time_start, time_end, dateFilter))
return None
raise ApiException(latest.status_code, "Nightscout last_uploaded_entry %s response: %s" % (latest.status_code, latest.text))
j = latest.json()
@@ -106,6 +109,9 @@ class NightscoutApi:
'api-secret': hashlib.sha1(self.secret.encode()).hexdigest()
}, verify=self.verify)
if latest.status_code != 200:
if 'as a valid ISO-8601 date' in latest.text:
logger.warning("Nightscout last_uploaded_bg_entry could not process ISO-8601 date: start=%s end=%s dateFilter=%s" % (time_start, time_end, dateFilter))
return None
raise ApiException(latest.status_code, "Nightscout last_uploaded_bg_entry %s response: %s" % (latest.status_code, latest.text))
j = latest.json()
@@ -134,6 +140,9 @@ class NightscoutApi:
'api-secret': hashlib.sha1(self.secret.encode()).hexdigest()
}, verify=self.verify)
if latest.status_code != 200:
if 'as a valid ISO-8601 date' in latest.text:
logger.warning("Nightscout activity %s could not process ISO-8601 date: start=%s end=%s dateFilter=%s" % (activityType, time_start, time_end, dateFilter))
return None
raise ApiException(latest.status_code, "Nightscout activity %s response: %s" % (latest.status_code, latest.text))
j = latest.json()
@@ -161,6 +170,9 @@ class NightscoutApi:
'api-secret': hashlib.sha1(self.secret.encode()).hexdigest()
}, verify=self.verify)
if latest.status_code != 200:
if 'as a valid ISO-8601 date' in latest.text:
logger.warning("Nightscout devicestatus could not process ISO-8601 date: start=%s end=%s dateFilter=%s" % (time_start, time_end, dateFilter))
return None
raise ApiException(latest.status_code, "Nightscout devicestatus %s response: %s" % (latest.status_code, latest.text))
j = latest.json()
+4 -2
View File
@@ -195,14 +195,16 @@ class NightscoutEntry:
}
@staticmethod
def devicestatus(created_at, batteryVoltage, batteryString, pump_event_id=""):
def devicestatus(created_at, batteryVoltage, batteryPercent, pump_event_id=""):
return {
"device": ENTERED_BY,
"created_at": created_at,
"pump": {
"clock": created_at,
"battery": {
"voltage": float(batteryVoltage),
"string": batteryString
"percent": int(batteryPercent) if batteryPercent else None,
"status": "%.0f%s" % (batteryPercent, '%')
},
},
"pump_event_id": pump_event_id
+7 -2
View File
@@ -69,7 +69,12 @@ class TandemSourceAutoupdate:
self.last_attempt_time = now
self.time_diffs_between_attempts = []
else:
logger.info('No new reported tandemsource data. (cur_max_date: %s)' % cur_max_date_with_events)
logger.info('No new reported tandemsource data. cur_max_date: %s (%dm ago) last_event_time: %s (%dm ago)' % (
arrow.get(cur_max_date_with_events) if cur_max_date_with_events else None,
(now - cur_max_date_with_events)//60 if cur_max_date_with_events else None,
arrow.get(self.last_event_time) if self.last_event_time else None,
(now - self.last_event_time)//60 if self.last_event_time else None
))
# If we haven't seen the pump event index update in AUTOUPDATE_NO_DATA_FAILURE_MINUTES,
# then trigger an error and potentially restart.
@@ -93,7 +98,7 @@ class TandemSourceAutoupdate:
# above no indexes warning.
elif self.last_successful_process_time_range and (now - self.last_successful_process_time_range) >= 60 * self.secret.AUTOUPDATE_FAILURE_MINUTES:
logger.error(AutoupdateNoNewDataDetectedError(
"%s: No new data has been detected via the API for %d minutes. " % (datetime.datetime.now(), (now - self.last_successful_process_time_range)//60) +
"%s: No new data has been detected via the API for %d minutes (last: %s). " % (datetime.datetime.now(), (now - self.last_successful_process_time_range)//60, self.last_successful_process_time_range) +
"tconnectsync might not be functioning properly."))
if self.secret.AUTOUPDATE_RESTART_ON_FAILURE:
@@ -59,7 +59,7 @@ class ProcessDeviceStatus:
return NightscoutEntry.devicestatus(
created_at=event.eventTimestamp.format(),
batteryVoltage=(float(event.batterylipomillivolts or 0)/1000),
batteryString="%.0f%s" % (100*event.batteryChargePercent, '%'),
batteryPercent=int(100*event.batteryChargePercent),
pump_event_id = "%s" % event.seqNum
)
@@ -49,7 +49,7 @@ class UpdateProfiles:
logger.info("Current pump settings: %s" % pump_settings)
ns_profile_obj = self.nightscout.current_profile()
logger.info("Current Nightscout profile: %s" % ns_profile_obj)
logger.debug("Current Nightscout profile: %s" % ns_profile_obj)
if ns_profile_obj is None:
ns_profile_obj = {}
@@ -95,7 +95,7 @@ class UpdateProfiles:
ns = ns_profile_obj.get('store', {})
logger.info("compare_profiles profile names: device: %s ns: %s", device.keys(), ns.keys())
logger.debug("compare_profiles profile names: device: %s ns: %s", device.keys(), ns.keys())
new_ns_profile = copy.deepcopy(ns_profile_obj)
if not 'store' in new_ns_profile:
@@ -113,12 +113,12 @@ class UpdateProfiles:
existent_profiles_in_ns = set(device.keys()) & set(ns.keys())
for profile_name in existent_profiles_in_ns:
logger.debug("Checking for differences for %s profile between pump and nightscout", profile_name)
#logger.debug("Checking for differences for %s profile between pump and nightscout", profile_name)
pump_configured_profile = device[profile_name]
ns_translated_profile = NightscoutEntry.tandemsource_profile_store(pump_configured_profile, pump_settings)
ns_configured_profile = ns[profile_name]
logger.debug("Comparing %s profile from pump: %s to nightscout: %s", profile_name, ns_translated_profile, ns_configured_profile)
#logger.debug("Comparing %s profile from pump: %s to nightscout: %s", profile_name, ns_translated_profile, ns_configured_profile)
if self.nightscout_profiles_identical(ns_configured_profile, ns_translated_profile):
logger.info("Profile %s identical between pump and nightscout", profile_name)
continue
@@ -37,8 +37,10 @@ class TestProcessDeviceStatus(unittest.TestCase):
'created_at': '2024-12-03 23:40:23-05:00',
'device': 'Pump (tconnectsync)',
'pump': {
'clock': '2024-12-03 23:40:23-05:00',
'battery': {
'string': '48%',
'status': '32%',
'percent': 32,
'voltage': 14.08
}
},
@@ -89,8 +91,10 @@ class TestProcessDeviceStatus(unittest.TestCase):
'created_at': '2024-12-04 02:30:23-05:00',
'device': 'Pump (tconnectsync)',
'pump': {
'clock': '2024-12-04 02:30:23-05:00',
'battery': {
'string': '47%',
'status': '31%',
'percent': 31,
'voltage': 13.824
}
},
@@ -131,8 +135,10 @@ class TestProcessDeviceStatus(unittest.TestCase):
'created_at': '2024-12-04 05:50:23-05:00',
'device': 'Pump (tconnectsync)',
'pump': {
'clock': '2024-12-04 05:50:23-05:00',
'battery': {
'string': '46%',
'status': '30%',
'percent': 30,
'voltage': 13.568
}
},