eventparser: use eventID consistently as seqNum

This commit is contained in:
James Woglom
2024-12-10 20:35:17 -05:00
parent dd2dcd17bd
commit 2b367d45f3
19 changed files with 465 additions and 100 deletions
+5 -1
View File
@@ -61,9 +61,13 @@ class {name}(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
'''
def firstLower(text):
+280 -56
View File
@@ -81,9 +81,13 @@ class LidBasalRateChange(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidAlertActivated(BaseEvent):
@@ -257,9 +261,13 @@ class LidAlertActivated(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidAlarmActivated(BaseEvent):
@@ -435,9 +443,13 @@ class LidAlarmActivated(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidMalfunctionActivated(BaseEvent):
@@ -472,9 +484,13 @@ class LidMalfunctionActivated(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidPumpingSuspended(BaseEvent):
@@ -530,9 +546,13 @@ class LidPumpingSuspended(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidPumpingResumed(BaseEvent):
@@ -561,9 +581,13 @@ class LidPumpingResumed(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidTimeChanged(BaseEvent):
@@ -595,9 +619,13 @@ class LidTimeChanged(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidDateChanged(BaseEvent):
@@ -629,9 +657,13 @@ class LidDateChanged(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidBgReadingTaken(BaseEvent):
@@ -749,9 +781,13 @@ class LidBgReadingTaken(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidBolusCompleted(BaseEvent):
@@ -817,9 +853,13 @@ class LidBolusCompleted(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidBolexCompleted(BaseEvent):
@@ -885,9 +925,13 @@ class LidBolexCompleted(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidAlertCleared(BaseEvent):
@@ -1055,9 +1099,13 @@ class LidAlertCleared(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidAlarmCleared(BaseEvent):
@@ -1224,9 +1272,13 @@ class LidAlarmCleared(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidCartridgeFilled(BaseEvent):
@@ -1255,9 +1307,13 @@ class LidCartridgeFilled(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidShelfMode(BaseEvent):
@@ -1298,9 +1354,13 @@ class LidShelfMode(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidBolusActivated(BaseEvent):
@@ -1352,9 +1412,13 @@ class LidBolusActivated(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidBolexActivated(BaseEvent):
@@ -1406,9 +1470,13 @@ class LidBolexActivated(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidDataLogCorruption(BaseEvent):
@@ -1437,9 +1505,13 @@ class LidDataLogCorruption(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidCannulaFilled(BaseEvent):
@@ -1489,9 +1561,13 @@ class LidCannulaFilled(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidTubingFilled(BaseEvent):
@@ -1544,9 +1620,13 @@ class LidTubingFilled(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidBolusRequestedMsg1(BaseEvent):
@@ -1633,9 +1713,13 @@ class LidBolusRequestedMsg1(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidBolusRequestedMsg2(BaseEvent):
@@ -1768,9 +1852,13 @@ class LidBolusRequestedMsg2(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidBolusRequestedMsg3(BaseEvent):
@@ -1805,9 +1893,13 @@ class LidBolusRequestedMsg3(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidNewDay(BaseEvent):
@@ -1839,9 +1931,13 @@ class LidNewDay(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidArmInit(BaseEvent):
@@ -1876,9 +1972,13 @@ class LidArmInit(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidPlgsPeriodic(BaseEvent):
@@ -2051,9 +2151,13 @@ class LidPlgsPeriodic(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidCgmAlertActivated(BaseEvent):
@@ -2117,9 +2221,13 @@ class LidCgmAlertActivated(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidCgmAlertCleared(BaseEvent):
@@ -2174,9 +2282,13 @@ class LidCgmAlertCleared(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidVersionInfo(BaseEvent):
@@ -2211,9 +2323,13 @@ class LidVersionInfo(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidUpdateStatus(BaseEvent):
@@ -2274,9 +2390,13 @@ class LidUpdateStatus(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidCgmStartSessionGx(BaseEvent):
@@ -2308,9 +2428,13 @@ class LidCgmStartSessionGx(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidCgmJoinSessionGx(BaseEvent):
@@ -2384,9 +2508,13 @@ class LidCgmJoinSessionGx(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidCgmStopSessionGx(BaseEvent):
@@ -2463,9 +2591,13 @@ class LidCgmStopSessionGx(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidAaUserModeChange(BaseEvent):
@@ -2682,9 +2814,13 @@ class LidAaUserModeChange(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidAaPcmChange(BaseEvent):
@@ -2861,9 +2997,13 @@ class LidAaPcmChange(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidCgmDataGxb(BaseEvent):
@@ -2992,9 +3132,13 @@ class LidCgmDataGxb(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidBasalDelivery(BaseEvent):
@@ -3055,9 +3199,13 @@ class LidBasalDelivery(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidBolusDelivery(BaseEvent):
@@ -3183,9 +3331,13 @@ class LidBolusDelivery(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidVersionsA(BaseEvent):
@@ -3220,9 +3372,13 @@ class LidVersionsA(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidAaDailyStatus(BaseEvent):
@@ -3317,9 +3473,13 @@ class LidAaDailyStatus(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidCgmAlertActivatedDex(BaseEvent):
@@ -3406,9 +3566,13 @@ class LidCgmAlertActivatedDex(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidCgmAlertClearedDex(BaseEvent):
@@ -3486,9 +3650,13 @@ class LidCgmAlertClearedDex(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidCgmAlertAckDex(BaseEvent):
@@ -3587,9 +3755,13 @@ class LidCgmAlertAckDex(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidCgmDataFsl2(BaseEvent):
@@ -3752,9 +3924,13 @@ class LidCgmDataFsl2(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidCgmJoinSessionG7(BaseEvent):
@@ -3783,9 +3959,13 @@ class LidCgmJoinSessionG7(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidCgmDataG7(BaseEvent):
@@ -3954,9 +4134,13 @@ class LidCgmDataG7(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidCgmStartSessionFsl2(BaseEvent):
@@ -3985,9 +4169,13 @@ class LidCgmStartSessionFsl2(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidCgmStopSessionFsl2(BaseEvent):
@@ -4022,9 +4210,13 @@ class LidCgmStopSessionFsl2(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidCgmJoinSessionFsl2(BaseEvent):
@@ -4059,9 +4251,13 @@ class LidCgmJoinSessionFsl2(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidCgmStopSessionG7(BaseEvent):
@@ -4102,9 +4298,13 @@ class LidCgmStopSessionG7(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidCgmAlertActivatedFsl2(BaseEvent):
@@ -4189,9 +4389,13 @@ class LidCgmAlertActivatedFsl2(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidCgmAlertClearedFsl2(BaseEvent):
@@ -4267,9 +4471,13 @@ class LidCgmAlertClearedFsl2(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidDailyBasal(BaseEvent):
@@ -4310,9 +4518,13 @@ class LidDailyBasal(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidCarbsEntered(BaseEvent):
@@ -4338,9 +4550,13 @@ class LidCarbsEntered(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidUsbConnected(BaseEvent):
@@ -4366,9 +4582,13 @@ class LidUsbConnected(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
@dataclass
class LidUsbDisconnected(BaseEvent):
@@ -4394,9 +4614,13 @@ class LidUsbDisconnected(BaseEvent):
return self.raw.timestamp
@property
def eventId(self):
def seqNum(self):
return self.raw.seqNum
@property
def eventId(self):
return self.ID
EVENT_IDS = {
3: LidBasalRateChange,
4: LidAlertActivated,
+1 -5
View File
@@ -26,7 +26,7 @@ class BaseEvent:
raise NotImplemented
@dataclass
class RawEvent(BaseEvent):
class RawEvent:
source: int
id: int
timestampRaw: int
@@ -63,8 +63,4 @@ class RawEvent(BaseEvent):
def eventTimestamp(self):
return self.timestamp
@property
def raw(self):
return self
+27
View File
@@ -154,6 +154,33 @@ class NightscoutApi:
else:
raise e
def last_uploaded_devicestatus(self, time_start=None, time_end=None):
def internal(t_to_space):
dateFilter = time_range('created_at', time_start, time_end, t_to_space=t_to_space)
latest = requests.get(urljoin(self.url, 'api/v1/devicestatus?find[device]=' + urllib.parse.quote(ENTERED_BY) + dateFilter + '&ts=' + str(time.time())), headers={
'api-secret': hashlib.sha1(self.secret.encode()).hexdigest()
}, verify=self.verify)
if latest.status_code != 200:
raise ApiException(latest.status_code, "Nightscout devicestatus %s response: %s" % (latest.status_code, latest.text))
j = latest.json()
if j and len(j) > 0:
return j[0]
return None
try:
ret = internal(False)
if ret is None and (time_start or time_end):
ret = internal(True)
if ret is not None:
logger.warning("devicestatus with activityType=%s time_start=%s time_end=%s only returned data when timestamps contained a space" % (activityType, time_start, time_end))
return ret
except requests.exceptions.ConnectionError as e:
if self.ignore_conn_errors:
logger.warn('Ignoring ConnectionError because ignore_conn_errors=true', e)
else:
raise e
"""
Returns general status information about the Nightscout server.
"""
+14
View File
@@ -194,6 +194,20 @@ class NightscoutEntry:
"pump_event_id": pump_event_id
}
@staticmethod
def devicestatus(created_at, batteryVoltage, batteryString, pump_event_id=""):
return {
"device": ENTERED_BY,
"created_at": created_at,
"pump": {
"battery": {
"voltage": float(batteryVoltage),
"string": batteryString
},
},
"pump_event_id": pump_event_id
}
# Tandem-scraped profile to Nightscout profile store entry
@staticmethod
def profile_store(profile: Profile, device_settings: DeviceSettings) -> dict:
+6 -6
View File
@@ -18,7 +18,7 @@ class TandemSourceAutoupdate:
self.last_max_date_with_events = None
self.last_event_time = 0
self.last_attempt_time = 0
self.last_event_index = None
self.last_event_seqnum = None
self.time_diffs_between_attempts = []
self.time_diffs_between_updates = []
@@ -42,7 +42,7 @@ class TandemSourceAutoupdate:
tconnectDevice = ChooseDevice(self.secret, tconnect).choose()
event_id = None
event_seqnum = None
cur_max_date_with_events = arrow.get(tconnectDevice['maxDateWithEvents']).float_timestamp
if not self.last_max_date_with_events or cur_max_date_with_events > self.last_max_date_with_events:
logger.info('New reported tandemsource data. (cur_max_date: %s last_max_date: %s)' % (cur_max_date_with_events, self.last_max_date_with_events))
@@ -50,20 +50,20 @@ class TandemSourceAutoupdate:
if pretend:
logger.info('Would update now if not in pretend mode')
else:
added, event_id = ProcessTimeRange(tconnect, nightscout, tconnectDevice, pretend, features=features).process(time_start, time_end)
added, event_seqnum = ProcessTimeRange(tconnect, nightscout, tconnectDevice, pretend, features=features).process(time_start, time_end)
logger.info('Added %d items from ProcessTimeRange' % added)
self.last_successful_process_time_range = now
# Track the time it took to find a new event between runs,
# but skip this calculation the first process cycle (since
# we don't know at what exact point the event index changed)
if self.last_event_index:
if self.last_event_seqnum:
self.time_diffs_between_updates.append(now - self.last_max_date_with_events)
logger.debug('Updating tracking of time since last update: %s' % self.time_diffs_between_updates)
# Mark the last event index uploaded from the pump and timestamp
if event_id:
self.last_event_index = event_id
if event_seqnum:
self.last_event_seqnum = event_seqnum
self.last_event_time = now
self.last_max_date_with_events = cur_max_date_with_events
self.last_attempt_time = now
@@ -0,0 +1,24 @@
from ...features import DEFAULT_FEATURES
from ...eventparser.generic import Events, decode_raw_events, EVENT_LEN
from .choose_device import ChooseDevice
from .process import ProcessTimeRange
from ...api import TConnectApi
from ... import secret
import datetime
import logging
logger = logging.getLogger(__name__)
def fetch_oneshot(username, password, time_start=None, time_end=None):
tconnect = TConnectApi(username, password)
if not time_start and not time_end:
time_end = datetime.datetime.now()
time_start = time_end - datetime.timedelta(days=1)
tconnectDevice = ChooseDevice(secret, tconnect).choose()
pump_events_raw = tconnect.tandemsource.pump_events_raw(tconnectDevice['tconnectDeviceId'], time_start, time_end)
pump_events_decoded = decode_raw_events(pump_events_raw)
logger.info(f"Read {len(pump_events_decoded)} bytes (est. {len(pump_events_decoded)/EVENT_LEN} events)")
return list(Events(pump_events_decoded))
+6 -6
View File
@@ -55,18 +55,18 @@ class ProcessTimeRange:
events_first_time = None
events_last_time = None
last_event_id = None # aka seqnum
last_event_seqnum = None
for_eventclass = collections.defaultdict(list)
for event in events:
if not events_first_time:
events_first_time = event.eventTimestamp
if not events_last_time:
events_last_time = event.eventTimestamp
if not last_event_id:
last_event_id = event.eventId
if not last_event_seqnum:
last_event_seqnum = event.seqNum
events_first_time = min(events_first_time, event.eventTimestamp)
events_last_time = max(events_last_time, event.eventTimestamp)
last_event_id = max(event.eventId, last_event_id)
last_event_seqnum = max(event.seqNum, last_event_seqnum)
clazz = EventClass.for_event(event)
if clazz:
@@ -97,6 +97,6 @@ class ProcessTimeRange:
else:
logger.info("Skipping %s, is not enabled from features %s" % (updater_class.__name__, self.features))
logger.info("Processed %d events. Last event ID seen: %d" % (processed_count if processed_count else 0, last_event_id if last_event_id else -1))
return processed_count, last_event_id
logger.info("Processed %d events. Last event ID seen: %d" % (processed_count if processed_count else 0, last_event_seqnum if last_event_seqnum else -1))
return processed_count, last_event_seqnum
@@ -63,11 +63,11 @@ class ProcessAlarm:
return NightscoutEntry.alarm(
created_at = event.eventTimestamp.format(),
reason = "%s" % event.alarmid.name,
pump_event_id = "%s" % event.eventId
pump_event_id = "%s" % event.seqNum
)
elif type(event) == eventtypes.LidMalfunctionActivated:
return NightscoutEntry.alarm(
created_at = event.eventTimestamp.format(),
reason = "Malfunction",
pump_event_id = "%s" % event.eventId
pump_event_id = "%s" % event.seqNum
)
@@ -85,7 +85,7 @@ class ProcessBasal:
duration_mins = duration.seconds / 60,
created_at = start.format(),
reason = ', '.join(bitmask_to_list(event.changetype)),
pump_event_id = "%s" % event.eventId
pump_event_id = "%s" % event.seqNum
)
if type(event) == eventtypes.LidBasalDelivery:
value = insulin_milliunits_to_real(event.commandedRate)
@@ -97,5 +97,5 @@ class ProcessBasal:
duration_mins = duration.seconds / 60,
created_at = start.format(),
reason = ', '.join(bitmask_to_list(event.commandedRateSource)),
pump_event_id = "%s" % event.eventId
pump_event_id = "%s" % event.seqNum
)
@@ -62,5 +62,5 @@ class ProcessBasalResume:
if type(event) == eventtypes.LidPumpingResumed:
return NightscoutEntry.basalresume(
created_at = event.eventTimestamp.format(),
pump_event_id = "%s" % event.eventId
pump_event_id = "%s" % event.seqNum
)
@@ -63,5 +63,5 @@ class ProcessBasalSuspension:
return NightscoutEntry.basalsuspension(
created_at = event.eventTimestamp.format(),
reason = ', '.join(bitmask_to_list(event.suspendreason)),
pump_event_id = "%s" % event.eventId
pump_event_id = "%s" % event.seqNum
)
@@ -46,7 +46,7 @@ class ProcessBolus:
if type(event) == eventtypes.LidBolusCompleted:
if last_upload_time and arrow.get(event.eventTimestamp) <= last_upload_time:
if self.pretend:
logger.info("Skipping bolusCompletedEvent before last upload time: %s (time range: %s - %s)" % (event, time_start, time_end))
logger.info("Skipping bolusCompletedEvent not after last upload time: %s (time range: %s - %s)" % (event, time_start, time_end))
continue
bolusCompletedEvents.append(event)
@@ -91,10 +91,10 @@ class ProcessBolus:
suffix = (' ' + (' '.join(suffixes))) if suffixes else ''
event_ids = []
seq_nums = []
for e in [bolusCompleted, bolusRequested1, bolusRequested2, bolusRequested3]:
if e:
event_ids.append(str(e.eventId))
seq_nums.append(str(e.seqNum))
notes = ''
if bolusRequested2 and str(bolusRequested2.optionsRaw) in eventtypes.LidBolusRequestedMsg2.OptionsMap:
@@ -107,6 +107,6 @@ class ProcessBolus:
created_at = bolusCompleted.eventTimestamp.format(),
notes = notes + suffix,
bg = bolusRequested1.BG if bolusRequested1 and bolusRequested1.BG > 0 else None,
pump_event_id = ",".join(event_ids)
pump_event_id = ",".join(seq_nums)
)
@@ -82,19 +82,19 @@ class ProcessCartridge:
return NightscoutEntry.sitechange(
created_at = cartFilled.eventTimestamp.format(),
reason = "Cartridge Filled" + (" (%du filled)" % round(cartFilled.v2Volume) if cartFilled.v2Volume else ""),
pump_event_id = "%s" % cartFilled.eventId
pump_event_id = "%s" % cartFilled.seqNum
)
def cannula_to_nsentry(self, cannulaFilled):
return NightscoutEntry.sitechange(
created_at = cannulaFilled.eventTimestamp.format(),
reason = "Cannula Filled" + (" (%du primed)" % round(cannulaFilled.primesize, 2) if cannulaFilled.primesize else ""),
pump_event_id = "%s" % cannulaFilled.eventId
pump_event_id = "%s" % cannulaFilled.seqNum
)
def tubing_to_nsentry(self, tubingFilled):
return NightscoutEntry.sitechange(
created_at = tubingFilled.eventTimestamp.format(),
reason = "Tubing Filled" + (" (%du primed)" % round(tubingFilled.primesize) if tubingFilled.primesize else ""),
pump_event_id = "%s" % tubingFilled.eventId
pump_event_id = "%s" % tubingFilled.seqNum
)
@@ -73,7 +73,7 @@ class ProcessCGMAlert:
return NightscoutEntry.cgm_alert(
created_at = alert.eventTimestamp.format(),
reason = ("CGM Alert (%s)" % alert.dalertid.name) if alert.dalertid else "CGM Alert (Unknown)",
pump_event_id = "%s" % alert.eventId
pump_event_id = "%s" % alert.seqNum
)
elif type(alert) == eventtypes.LidCgmAlertActivatedDex:
if alert.dalertid == eventtypes.LidCgmAlertActivatedDex.DalertidEnum.CgmOutOfRange:
@@ -82,11 +82,11 @@ class ProcessCGMAlert:
return NightscoutEntry.cgm_alert(
created_at = alert.eventTimestamp.format(),
reason = ("Dexcom CGM Alert (%s)" % alert.dalertid.name) if alert.dalertid else "Dexcom CGM Alert (Unknown)",
pump_event_id = "%s" % alert.eventId
pump_event_id = "%s" % alert.seqNum
)
elif type(alert) == eventtypes.LidCgmAlertActivatedFsl2:
return NightscoutEntry.cgm_alert(
created_at = alert.eventTimestamp.format(),
reason = ("Libre CGM Alert (%s)" % alert.dalertid.name) if alert.dalertid else "Libre CGM Alert (Unknown)",
pump_event_id = "%s" % alert.eventId
pump_event_id = "%s" % alert.seqNum
)
@@ -72,5 +72,5 @@ class ProcessCGMReading:
return NightscoutEntry.entry(
sgv = event.currentglucosedisplayvalue,
created_at = self.timestamp_for(event).format(),
pump_event_id = "%s" % event.eventId,
pump_event_id = "%s" % event.seqNum,
)
@@ -80,17 +80,17 @@ class ProcessCGMStartJoinStop:
return NightscoutEntry.cgm_start(
created_at = event.eventTimestamp.format(),
reason = "CGM Session Started",
pump_event_id = "%s" % event.eventId
pump_event_id = "%s" % event.seqNum
)
elif type(event) in EventClass._CGM_JOIN:
return NightscoutEntry.cgm_join(
created_at = event.eventTimestamp.format(),
reason = "CGM Session Joined",
pump_event_id = "%s" % event.eventId
pump_event_id = "%s" % event.seqNum
)
elif type(event) in EventClass._CGM_STOP:
return NightscoutEntry.cgm_stop(
created_at = event.eventTimestamp.format(),
reason = "CGM Session Stopped",
pump_event_id = "%s" % event.eventId
pump_event_id = "%s" % event.seqNum
)
@@ -0,0 +1,76 @@
import logging
import arrow
from ...features import DEFAULT_FEATURES
from ... import features
from ...eventparser.generic import Events, decode_raw_events, EVENT_LEN
from ...eventparser.utils import bitmask_to_list
from ...eventparser import events as eventtypes
from ...domain.tandemsource.event_class import EventClass
from ...parser.nightscout import (
EXERCISE_EVENTTYPE,
SLEEP_EVENTTYPE,
NightscoutEntry
)
logger = logging.getLogger(__name__)
class ProcessDeviceStatus:
def __init__(self, tconnect, nightscout, tconnect_device_id, pretend, features=DEFAULT_FEATURES):
self.tconnect = tconnect
self.nightscout = nightscout
self.tconnect_device_id = tconnect_device_id
self.pretend = pretend
self.features = features
def enabled(self):
return features.PUMP_EVENTS in self.features
def process(self, events, time_start, time_end):
logger.debug("ProcessDeviceStatus: querying for last uploaded devicestatus")
last_upload = self.nightscout.last_uploaded_devicestatus(time_start=time_start, time_end=time_end)
last_upload_time = None
if last_upload:
last_upload_time = arrow.get(last_upload["created_at"])
logger.info("ProcessDeviceStatus: Last Nightscout devicestatus upload: %s" % last_upload_time)
last_daily_basal_event = None
for event in sorted(events, key=lambda x: self.timestamp_for(x)):
if last_upload_time and self.timestamp_for(event) <= last_upload_time:
if self.pretend:
logger.info("ProcessDeviceStatus: Skipping %s not after last upload time: %s (time range: %s - %s)" % (type(event), event, time_start, time_end))
continue
if isinstance(event, eventtypes.LidDailyBasal):
last_daily_basal_event = event
if not last_daily_basal_event:
logger.info("ProcessDeviceStatus: No last_daily_basal_event found for add (time range: %s - %s)" % (time_start, time_end))
ns_entries = []
ns_entries.append(self.daily_basal_to_nsentry(last_daily_basal_event))
return ns_entries
def daily_basal_to_nsentry(event):
return NightscoutEntry.devicestatus(
created_at=event.eventTimestamp.format(),
batteryVoltage=(float(event.batterylipomillivolts or 0)/1000),
batteryString="%s%s" % (event.batterychargepercent, '%'),
pump_event_id = "%s" % event.seqNum
)
def write(self, ns_entries):
count = 0
for entry in ns_entries:
if self.pretend:
logger.info("Would upload devicestatus to Nightscout: %s" % entry)
else:
logger.info("Uploading devicestatus to Nightscout: %s" % entry)
self.nightscout.upload_entry(entry, entity='devicestatus')
count += 1
return count
@@ -157,7 +157,7 @@ class ProcessUserMode:
reason=reason,
duration=duration_mins,
event_type=SLEEP_EVENTTYPE,
pump_event_id = "%s,%s" % (start.eventId, stop.eventId)
pump_event_id = "%s,%s" % (start.seqNum, stop.seqNum)
)
elif start:
reason = None
@@ -172,7 +172,7 @@ class ProcessUserMode:
reason=reason + " - " + NOT_ENDED if reason else NOT_ENDED,
duration=duration_mins,
event_type=SLEEP_EVENTTYPE,
pump_event_id = "%s" % start.eventId
pump_event_id = "%s" % start.seqNum
)
@@ -191,7 +191,7 @@ class ProcessUserMode:
reason=reason,
duration=duration_mins,
event_type=EXERCISE_EVENTTYPE,
pump_event_id = "%s,%s" % (start.eventId, stop.eventId)
pump_event_id = "%s,%s" % (start.seqNum, stop.seqNum)
)
elif start:
reason = "Exercise"
@@ -204,7 +204,7 @@ class ProcessUserMode:
reason=reason + " - " + NOT_ENDED,
duration=duration_mins,
event_type=EXERCISE_EVENTTYPE,
pump_event_id = "%s" % start.eventId
pump_event_id = "%s" % start.seqNum
)
def process_unended_sleep_stop(self, event, sleep_last_upload):
@@ -220,7 +220,7 @@ class ProcessUserMode:
reason=sleep_last_upload["reason"].replace(" - %s" % NOT_ENDED, ""),
duration=duration_mins,
event_type=SLEEP_EVENTTYPE,
pump_event_id="%s,%s" % (sleep_last_upload.get("pump_event_id",""), event.eventId)
pump_event_id="%s,%s" % (sleep_last_upload.get("pump_event_id",""), event.seqNum)
)
def process_unended_exercise_stop(self, event, exercise_last_upload):
@@ -240,5 +240,5 @@ class ProcessUserMode:
reason=reason,
duration=duration_mins,
event_type=EXERCISE_EVENTTYPE,
pump_event_id="%s,%s" % (exercise_last_upload.get("pump_event_id",""), event.eventId)
pump_event_id="%s,%s" % (exercise_last_upload.get("pump_event_id",""), event.seqNum)
)