Sync events.json to upstream schema; preserve camelCase attribute names

Copy the exact eventSchema.json to events.json (camelCase keys) and fix
build_events.py's fieldNameFormat to preserve camelCase instead of collapsing
it via .title() (which turned schema keys like commandedRate into commandedrate).
Regenerate events.py so attributes are clean camelCase (commandedRate,
currentGlucoseDisplayValue, egvTimeStamp, bolusId, ...); acronyms follow the
schema's own casing (bg, iob, rssi). Update the battery transform and all
attribute references in the process handlers and tests to match.
This commit is contained in:
James Woglom
2026-07-01 06:50:30 +00:00
parent e5304dc605
commit ee7384cc31
48 changed files with 1932 additions and 1927 deletions
+6 -1
View File
@@ -119,7 +119,12 @@ def eventNameFormat(text):
def fieldNameFormat(text):
if not text or all([i.isupper() for i in text]):
return text
return firstLower(text.replace('_', ' ').title().replace(' ', '')).replace('raw', 'Raw')
if '_' in text or ' ' in text:
# snake_case / space-separated -> CamelCase, then lowercase first char
return firstLower(text.replace('_', ' ').title().replace(' ', '')).replace('raw', 'Raw')
# already camelCase (schema keys): preserve internal capitalization, only
# lowercase the first character (don't .title() it away)
return firstLower(text)
def build_fields(event_def):
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -142,7 +142,7 @@ def transform_battery_charge_percent(event_def, name, name_fmt, field, tx):
out += [
'@property',
f'def batteryChargePercent(self):',
f' return (256*(self.batterychargepercentmsbRaw-14)+self.batterychargepercentlsbRaw)/(3*256)',
f' return (256*(self.batteryChargePercentMSBRaw-14)+self.batteryChargePercentLSBRaw)/(3*256)',
''
]
@@ -55,7 +55,7 @@ class ProcessAlarm:
return ns_entries
def skip_event(self, event: "BaseEvent") -> bool:
return event.alarmid in (
return event.alarmId in (
eventtypes.LidAlarmActivated.AlarmidEnum.ResumePumpAlarm,
eventtypes.LidAlarmActivated.AlarmidEnum.ResumePumpAlarm2
)
@@ -77,7 +77,7 @@ class ProcessAlarm:
if type(event) == eventtypes.LidAlarmActivated:
return NightscoutEntry.alarm(
created_at = event.eventTimestamp.format(),
reason = "%s" % event.alarmid.name,
reason = "%s" % event.alarmId.name,
pump_event_id = "%s" % event.seqNum
)
elif type(event) == eventtypes.LidMalfunctionActivated:
@@ -83,7 +83,7 @@ class ProcessBasal:
def basal_to_nsentry(self, start: arrow.Arrow, duration: datetime.timedelta, event: "BaseEvent") -> Optional[dict]:
if type(event) == eventtypes.LidBasalRateChange:
value = insulin_float_round(event.commandedbasalrate)
value = insulin_float_round(event.commandedBasalRate)
if IGNORE_ZERO_UNIT_BASAL and value < 0.01:
logger.info("Ignoring basal entry with %.2f unit basal because IGNORE_ZERO_UNIT_BASAL=true: %s" % (value, event))
return None
@@ -91,7 +91,7 @@ class ProcessBasal:
value = value,
duration_mins = duration.total_seconds() / 60,
created_at = start.format(),
reason = ', '.join(bitmask_to_list(event.changetype)),
reason = ', '.join(bitmask_to_list(event.changeType)),
pump_event_id = "%s" % event.seqNum
)
if type(event) == eventtypes.LidBasalDelivery:
@@ -68,6 +68,6 @@ class ProcessBasalSuspension:
if type(event) == eventtypes.LidPumpingSuspended:
return NightscoutEntry.basalsuspension(
created_at = event.eventTimestamp.format(),
reason = ', '.join(bitmask_to_list(event.suspendreason)),
reason = ', '.join(bitmask_to_list(event.suspendReason)),
pump_event_id = "%s" % event.seqNum
)
@@ -43,7 +43,7 @@ class ProcessBolus:
# Correlate a bolus's request/completion messages by bolusid.
bolusEventsForId = {}
for event in sorted(events, key=lambda x: x.eventTimestamp):
bolusEventsForId.setdefault(event.bolusid, {})[type(event)] = event
bolusEventsForId.setdefault(event.bolusId, {})[type(event)] = event
# Emit one Nightscout treatment per completion event, each at its own time:
# - LidBolusCompleted -> the standard / "now" bolus (carbs, bg, notes)
@@ -67,7 +67,7 @@ class ProcessBolus:
ns_entries.append(self.bolex_to_nsentry(event))
continue
m = bolusEventsForId[event.bolusid]
m = bolusEventsForId[event.bolusId]
ns_entries.append(self.bolus_to_nsentry(
event,
bolusRequested1 = m.get(eventtypes.LidBolusRequestedMsg1),
@@ -92,10 +92,10 @@ class ProcessBolus:
def bolus_to_nsentry(self, bolusCompleted: "BaseEvent", bolusRequested1: "BaseEvent", bolusRequested2: "BaseEvent", bolusRequested3: "BaseEvent") -> Optional[dict]:
suffixes = []
if bolusRequested2 and bolusRequested2.useroverride == eventtypes.LidBolusRequestedMsg2.UseroverrideEnum.Yes:
if bolusRequested2 and bolusRequested2.userOverride == eventtypes.LidBolusRequestedMsg2.UseroverrideEnum.Yes:
suffixes.append('(Override)')
if bolusRequested2 and bolusRequested2.declinedcorrection == eventtypes.LidBolusRequestedMsg2.DeclinedcorrectionEnum.Yes:
if bolusRequested2 and bolusRequested2.declinedCorrection == eventtypes.LidBolusRequestedMsg2.DeclinedcorrectionEnum.Yes:
suffixes.append('(Declined Correction)')
suffix = (' ' + (' '.join(suffixes))) if suffixes else ''
@@ -111,11 +111,11 @@ class ProcessBolus:
return NightscoutEntry.bolus(
bolus = insulin_float_round(bolusCompleted.insulindelivered),
carbs = bolusRequested1.carbamount if bolusRequested1 and bolusRequested1.carbamount>0 else None,
bolus = insulin_float_round(bolusCompleted.insulinDelivered),
carbs = bolusRequested1.carbAmount if bolusRequested1 and bolusRequested1.carbAmount>0 else None,
created_at = bolusCompleted.eventTimestamp.format(),
notes = notes + suffix,
bg = bolusRequested1.BG if bolusRequested1 and bolusRequested1.BG > 0 else None,
bg = bolusRequested1.bg if bolusRequested1 and bolusRequested1.bg > 0 else None,
pump_event_id = ",".join(seq_nums)
)
@@ -124,7 +124,7 @@ class ProcessBolus:
# the time it finished delivering. Insulin only; carbs/bg belong to the
# initial LidBolusCompleted entry and must not be double-counted here.
return NightscoutEntry.bolus(
bolus = insulin_float_round(bolexCompleted.insulindelivered),
bolus = insulin_float_round(bolexCompleted.insulinDelivered),
carbs = None,
created_at = bolexCompleted.eventTimestamp.format(),
notes = "Extended Bolus",
@@ -86,7 +86,7 @@ class ProcessCartridge:
def cart_to_nsentry(self, cartFilled: "BaseEvent") -> Optional[dict]:
# insulinVolume is populated on t:slim X2 / Mobi; v2Volume is a legacy fallback.
volume = cartFilled.insulinvolume or cartFilled.v2Volume
volume = cartFilled.insulinVolume or cartFilled.v2Volume
return NightscoutEntry.sitechange(
created_at = cartFilled.eventTimestamp.format(),
reason = "Cartridge Filled" + (" (%du filled)" % round(volume) if volume else ""),
@@ -95,7 +95,7 @@ class ProcessCartridge:
def cannula_to_nsentry(self, cannulaFilled: "BaseEvent") -> Optional[dict]:
# primeSize is fractional (e.g. 0.3u); format with one decimal, not %d.
primed = cannulaFilled.primesize if cannulaFilled.primesize and cannulaFilled.primesize > 0 else None
primed = cannulaFilled.primeSize if cannulaFilled.primeSize and cannulaFilled.primeSize > 0 else None
return NightscoutEntry.sitechange(
created_at = cannulaFilled.eventTimestamp.format(),
reason = "Cannula Filled" + (" (%.1fu primed)" % primed if primed else ""),
@@ -104,7 +104,7 @@ class ProcessCartridge:
def tubing_to_nsentry(self, tubingFilled: "BaseEvent") -> Optional[dict]:
# primeSize is -1 (sentinel, "not recorded") on real tubing fills; only show a real prime volume.
primed = tubingFilled.primesize if tubingFilled.primesize and tubingFilled.primesize > 0 else None
primed = tubingFilled.primeSize if tubingFilled.primeSize and tubingFilled.primeSize > 0 else None
return NightscoutEntry.sitechange(
created_at = tubingFilled.eventTimestamp.format(),
reason = "Tubing Filled" + (" (%du primed)" % round(primed) if primed else ""),
@@ -73,28 +73,28 @@ class ProcessCGMAlert:
def alert_to_nsentry(self, alert: "BaseEvent") -> Optional[dict]:
# FSL3 alert codes are defined in eventparser/static_dicts.py:CGM_ALERTS_DICT
# Alert code meanings are documented in comments there.
if not alert.dalertid:
logger.info("ProcessCGMAlert: Skipping alert with unknown dalertid %d: %s" % (alert.dalertidRaw, alert))
if not alert.dalertId:
logger.info("ProcessCGMAlert: Skipping alert with unknown dalertid %d: %s" % (alert.dalertIdRaw, alert))
return None
if type(alert) == eventtypes.LidCgmAlertActivated:
return NightscoutEntry.cgm_alert(
created_at = alert.eventTimestamp.format(),
reason = ("CGM Alert (%s)" % alert.dalertid.name) if alert.dalertid else "CGM Alert (Unknown)",
reason = ("CGM Alert (%s)" % alert.dalertId.name) if alert.dalertId else "CGM Alert (Unknown)",
pump_event_id = "%s" % alert.seqNum
)
elif type(alert) == eventtypes.LidCgmAlertActivatedDex:
if alert.dalertid == eventtypes.LidCgmAlertActivatedDex.DalertidEnum.CgmOutOfRange:
logger.info("ProcessCGMAlert: Skipping alert with CgmOutOfRange dalertid %d: %s" % (alert.dalertidRaw, alert))
if alert.dalertId == eventtypes.LidCgmAlertActivatedDex.DalertidEnum.CgmOutOfRange:
logger.info("ProcessCGMAlert: Skipping alert with CgmOutOfRange dalertid %d: %s" % (alert.dalertIdRaw, alert))
return None
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)",
reason = ("Dexcom CGM Alert (%s)" % alert.dalertId.name) if alert.dalertId else "Dexcom CGM Alert (Unknown)",
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)",
reason = ("Libre CGM Alert (%s)" % alert.dalertId.name) if alert.dalertId else "Libre CGM Alert (Unknown)",
pump_event_id = "%s" % alert.seqNum
)
@@ -48,8 +48,8 @@ def _resolve_glucose_value(display_value, status, *, precise, high, low):
# to be consistent across sensor types (e.g. G6 names its members differently), so
# every branch resolves against that sensor's own enum members.
def determine_glucose_value(event: CgmReadingEvent) -> int:
display_value = event.currentglucosedisplayvalue
status = event.glucosevaluestatus
display_value = event.currentGlucoseDisplayValue
status = event.glucoseValueStatus
if isinstance(event, eventtypes.LidCgmDataG7):
e = eventtypes.LidCgmDataG7.GlucosevaluestatusEnum
@@ -123,7 +123,7 @@ class ProcessCGMReading:
def timestamp_for(self, event: "BaseEvent") -> arrow.Arrow:
# For backfills the time the event was added to the pump's event store
# might not be the time it actually occurred, so we use the egvTimestamp
return arrow.get(TANDEM_EPOCH + event.egvTimestamp, tzinfo='UTC').replace(tzinfo=self.timezone)
return arrow.get(TANDEM_EPOCH + event.egvTimeStamp, tzinfo='UTC').replace(tzinfo=self.timezone)
def to_nsentry(self, event: "BaseEvent") -> Optional[dict]:
return NightscoutEntry.entry(
@@ -73,13 +73,13 @@ class ProcessDeviceStatus:
# The battery percent is derived from the msb/lsb raw fields; if the
# event arrived without them (an event shape we can't yet parse), skip
# it rather than raise on the arithmetic below.
if event.batterychargepercentmsbRaw is None or event.batterychargepercentlsbRaw is None:
if event.batteryChargePercentMSBRaw is None or event.batteryChargePercentLSBRaw is None:
logger.warning("ProcessDeviceStatus: skipping daily basal event missing battery data: %s" % event)
return None
return NightscoutEntry.devicestatus(
created_at=event.eventTimestamp.format(),
batteryVoltage=(float(event.batterylipomillivolts or 0)/1000),
batteryVoltage=(float(event.batteryLipoMilliVolts or 0)/1000),
batteryPercent=int(100*event.batteryChargePercent),
pump_event_id = "%s" % event.seqNum
)
@@ -138,23 +138,23 @@ class ProcessUserMode:
return count
def is_start_sleep(self, event: "BaseEvent") -> bool:
return event.requestedaction == eventtypes.LidAaUserModeChange.RequestedactionEnum.StartSleep
return event.requestedAction == eventtypes.LidAaUserModeChange.RequestedactionEnum.StartSleep
def is_stop_sleep(self, event: "BaseEvent") -> bool:
return event.requestedaction == eventtypes.LidAaUserModeChange.RequestedactionEnum.StopSleep or \
event.requestedaction == eventtypes.LidAaUserModeChange.RequestedactionEnum.StopAll
return event.requestedAction == eventtypes.LidAaUserModeChange.RequestedactionEnum.StopSleep or \
event.requestedAction == eventtypes.LidAaUserModeChange.RequestedactionEnum.StopAll
def is_start_exercise(self, event: "BaseEvent") -> bool:
return event.requestedaction == eventtypes.LidAaUserModeChange.RequestedactionEnum.StartExercise
return event.requestedAction == eventtypes.LidAaUserModeChange.RequestedactionEnum.StartExercise
def is_stop_exercise(self, event: "BaseEvent") -> bool:
return event.requestedaction == eventtypes.LidAaUserModeChange.RequestedactionEnum.StopExercise or \
event.requestedaction == eventtypes.LidAaUserModeChange.RequestedactionEnum.StopAll
return event.requestedAction == eventtypes.LidAaUserModeChange.RequestedactionEnum.StopExercise or \
event.requestedAction == eventtypes.LidAaUserModeChange.RequestedactionEnum.StopAll
def sleep_to_nsentry(self, start: "BaseEvent", stop: Optional["BaseEvent"] = None, time_end: Optional[arrow.Arrow] = None) -> Optional[dict]:
if start and stop:
reason = None
if start.sleepstartedbygui == eventtypes.LidAaUserModeChange.SleepstartedbyguiEnum.TrueVal:
if start.sleepStartedByGui == eventtypes.LidAaUserModeChange.SleepstartedbyguiEnum.TrueVal:
reason = "Sleep (Manual)"
elif start.activesleepschedule:
elif start.activeSleepSchedule:
reason = "Sleep (Scheduled)"
duration_mins = (stop.eventTimestamp - start.eventTimestamp).total_seconds() / 60
@@ -167,9 +167,9 @@ class ProcessUserMode:
)
elif start:
reason = None
if start.sleepstartedbygui == eventtypes.LidAaUserModeChange.SleepstartedbyguiEnum.TrueVal:
if start.sleepStartedByGui == eventtypes.LidAaUserModeChange.SleepstartedbyguiEnum.TrueVal:
reason = "Sleep (Manual)"
elif start.activesleepscheduleRaw:
elif start.activeSleepScheduleRaw:
reason = "Sleep (Scheduled)"
duration_mins = (time_end - start.eventTimestamp).total_seconds() / 60
@@ -185,10 +185,10 @@ class ProcessUserMode:
def exercise_to_nsentry(self, start: "BaseEvent", stop: Optional["BaseEvent"] = None, time_end: Optional[arrow.Arrow] = None) -> Optional[dict]:
if start and stop:
reason = "Exercise"
if start.exercisechoice == eventtypes.LidAaUserModeChange.ExercisechoiceEnum.Timed:
if start.exerciseChoice == eventtypes.LidAaUserModeChange.ExercisechoiceEnum.Timed:
reason = "Exercise (Timed)"
if stop.exercisestoppedbytimer == eventtypes.LidAaUserModeChange.ExercisestoppedbytimerEnum.TrueVal:
if stop.exerciseStoppedByTimer == eventtypes.LidAaUserModeChange.ExercisestoppedbytimerEnum.TrueVal:
reason += " (Stopped by timer)"
duration_mins = (stop.eventTimestamp - start.eventTimestamp).total_seconds() / 60
@@ -201,7 +201,7 @@ class ProcessUserMode:
)
elif start:
reason = "Exercise"
if start.exercisechoice == eventtypes.LidAaUserModeChange.ExercisechoiceEnum.Timed:
if start.exerciseChoice == eventtypes.LidAaUserModeChange.ExercisechoiceEnum.Timed:
reason = "Exercise (Timed)"
duration_mins = (time_end - start.eventTimestamp).total_seconds() / 60
@@ -237,7 +237,7 @@ class ProcessUserMode:
self.nightscout.delete_entry('treatments/%s' % exercise_last_upload["_id"])
reason = exercise_last_upload["reason"].replace(" - %s" % NOT_ENDED, "")
if event.exercisestoppedbytimer == eventtypes.LidAaUserModeChange.ExercisestoppedbytimerEnum.TrueVal:
if event.exerciseStoppedByTimer == eventtypes.LidAaUserModeChange.ExercisestoppedbytimerEnum.TrueVal:
reason += " (Stopped by timer)"
duration_mins = (event.eventTimestamp - arrow.get(exercise_last_upload["created_at"])).total_seconds() / 60
+9 -9
View File
@@ -382,11 +382,11 @@ class TestPumpEventsRealEventTypes(unittest.TestCase):
e = self._parse()["LidBolusCompleted"]
self.assertEqual(e.eventId, 20)
self.assertEqual(e.seqNum, 201)
self.assertEqual(e.bolusid, 777)
self.assertEqual(e.insulindelivered, 2.5)
self.assertEqual(e.insulinrequested, 2.5)
self.assertEqual(e.IOB, 1.1)
self.assertEqual(e.completionstatus,
self.assertEqual(e.bolusId, 777)
self.assertEqual(e.insulinDelivered, 2.5)
self.assertEqual(e.insulinRequested, 2.5)
self.assertEqual(e.iob, 1.1)
self.assertEqual(e.completionStatus,
eventtypes.LidBolusCompleted.CompletionstatusEnum.Completed)
def test_basal_delivery_decodes(self):
@@ -402,8 +402,8 @@ class TestPumpEventsRealEventTypes(unittest.TestCase):
e = self._parse()["LidCgmDataG7"]
self.assertEqual(e.eventId, 399)
self.assertEqual(e.seqNum, 203)
self.assertEqual(e.currentglucosedisplayvalue, 112)
self.assertEqual(e.glucosevaluestatus,
self.assertEqual(e.currentGlucoseDisplayValue, 112)
self.assertEqual(e.glucoseValueStatus,
eventtypes.LidCgmDataG7.GlucosevaluestatusEnum.PreciseValue)
# cgmDataType bitmask array [0] -> bit 0 set -> Fmr
self.assertEqual(e.cgmDataType,
@@ -415,9 +415,9 @@ class TestPumpEventsRealEventTypes(unittest.TestCase):
e = self._parse()["LidAlarmActivated"]
self.assertEqual(e.eventId, 5)
self.assertEqual(e.seqNum, 204)
self.assertEqual(e.faultlocatordata, 100)
self.assertEqual(e.faultLocatorData, 100)
self.assertEqual(e.param2, 2.0)
self.assertEqual(e.alarmid,
self.assertEqual(e.alarmId,
eventtypes.LidAlarmActivated.AlarmidEnum.OcclusionAlarm)
@@ -60,15 +60,15 @@ class TestLidAaDailyStatus(unittest.TestCase):
def test_pumpcontrolstate_closed_loop(self):
ev = Event(self.fixtureClosedLoop)
self.assertEqual(ev.pumpcontrolstateRaw, 3)
self.assertEqual(ev.pumpcontrolstate,
self.assertEqual(ev.pumpControlStateRaw, 3)
self.assertEqual(ev.pumpControlState,
eventtypes.LidAaDailyStatus.PumpcontrolstateEnum.PcmClosedLoop)
def test_pumpcontrolstate_no_control_zero_value(self):
# pumpControlState 0 must resolve, not be treated as missing.
ev = Event(self.fixtureNoControl)
self.assertEqual(ev.pumpcontrolstateRaw, 0)
self.assertEqual(ev.pumpcontrolstate,
self.assertEqual(ev.pumpControlStateRaw, 0)
self.assertEqual(ev.pumpControlState,
eventtypes.LidAaDailyStatus.PumpcontrolstateEnum.PcmNoControlNoCartridgeInstalled)
def test_usermode_resolves(self):
@@ -79,8 +79,8 @@ class TestLidAaDailyStatus(unittest.TestCase):
def test_sensortype_resolves(self):
ev = Event(self.fixtureClosedLoop)
self.assertEqual(ev.sensortypeRaw, 3)
self.assertEqual(ev.sensortype,
self.assertEqual(ev.sensorTypeRaw, 3)
self.assertEqual(ev.sensorType,
eventtypes.LidAaDailyStatus.SensortypeEnum.CgmTypeDexcomG7)
def test_unknown_keys_ignored(self):
@@ -98,9 +98,9 @@ class TestLidAaDailyStatus(unittest.TestCase):
self.assertEqual(d["id"], 313)
self.assertEqual(d["name"], "LID_AA_DAILY_STATUS")
self.assertEqual(d["seqNum"], 393118)
self.assertEqual(d["pumpcontrolstateRaw"], 3)
self.assertEqual(d["pumpControlStateRaw"], 3)
self.assertEqual(d["usermodeRaw"], 1)
self.assertEqual(d["sensortypeRaw"], 3)
self.assertEqual(d["sensorTypeRaw"], 3)
if __name__ == "__main__":
+20 -20
View File
@@ -78,58 +78,58 @@ class TestLidAaPcmChange(unittest.TestCase):
def test_pcm_enums_no_control_from_closed_loop(self):
# currentPcm:0 -> NoControl, previousPcm:3 -> ClosedLoop
ev = Event(self.fixtureSuspendedNoControl)
self.assertEqual(ev.currentpcmRaw, 0)
self.assertEqual(ev.currentpcm,
self.assertEqual(ev.currentPcmRaw, 0)
self.assertEqual(ev.currentPcm,
eventtypes.LidAaPcmChange.CurrentpcmEnum.NoControl)
self.assertEqual(ev.previouspcmRaw, 3)
self.assertEqual(ev.previouspcm,
self.assertEqual(ev.previousPcmRaw, 3)
self.assertEqual(ev.previousPcm,
eventtypes.LidAaPcmChange.PreviouspcmEnum.ClosedLoop)
def test_pcm_enums_closed_loop_from_no_control(self):
# currentPcm:3 -> ClosedLoop, previousPcm:0 -> NoControl
ev = Event(self.fixtureResumedClosedLoop)
self.assertEqual(ev.currentpcm,
self.assertEqual(ev.currentPcm,
eventtypes.LidAaPcmChange.CurrentpcmEnum.ClosedLoop)
self.assertEqual(ev.previouspcm,
self.assertEqual(ev.previousPcm,
eventtypes.LidAaPcmChange.PreviouspcmEnum.NoControl)
def test_pcm_enum_pining(self):
# currentPcm:2 -> Pining
ev = Event(self.fixturePiningNoCgm)
self.assertEqual(ev.currentpcmRaw, 2)
self.assertEqual(ev.currentpcm,
self.assertEqual(ev.currentPcmRaw, 2)
self.assertEqual(ev.currentPcm,
eventtypes.LidAaPcmChange.CurrentpcmEnum.Pining)
def test_boolean_fields_when_suspended(self):
ev = Event(self.fixtureSuspendedNoControl)
self.assertEqual(ev.pumpsuspendedRaw, 1)
self.assertEqual(ev.pumpsuspended,
self.assertEqual(ev.pumpSuspendedRaw, 1)
self.assertEqual(ev.pumpSuspended,
eventtypes.LidAaPcmChange.PumpsuspendedEnum.TrueVal)
self.assertEqual(ev.calculationavailable,
self.assertEqual(ev.calculationAvailable,
eventtypes.LidAaPcmChange.CalculationavailableEnum.TrueVal)
self.assertEqual(ev.cgmavailable,
self.assertEqual(ev.cgmAvailable,
eventtypes.LidAaPcmChange.CgmavailableEnum.TrueVal)
self.assertEqual(ev.closedlooppreferred,
self.assertEqual(ev.closedLoopPreferred,
eventtypes.LidAaPcmChange.ClosedlooppreferredEnum.TrueVal)
self.assertEqual(ev.sufficientclosedloopparams,
self.assertEqual(ev.sufficientClosedLoopParams,
eventtypes.LidAaPcmChange.SufficientclosedloopparamsEnum.TrueVal)
def test_pump_suspended_false(self):
# pumpSuspended:0 -> FalseVal (0 must not be treated as missing)
ev = Event(self.fixtureResumedClosedLoop)
self.assertEqual(ev.pumpsuspendedRaw, 0)
self.assertEqual(ev.pumpsuspended,
self.assertEqual(ev.pumpSuspendedRaw, 0)
self.assertEqual(ev.pumpSuspended,
eventtypes.LidAaPcmChange.PumpsuspendedEnum.FalseVal)
def test_cgm_available_false(self):
# cgmAvailable:0 -> FalseVal while other boolean-ish fields stay TrueVal
ev = Event(self.fixturePiningNoCgm)
self.assertEqual(ev.cgmavailableRaw, 0)
self.assertEqual(ev.cgmavailable,
self.assertEqual(ev.cgmAvailableRaw, 0)
self.assertEqual(ev.cgmAvailable,
eventtypes.LidAaPcmChange.CgmavailableEnum.FalseVal)
self.assertEqual(ev.calculationavailable,
self.assertEqual(ev.calculationAvailable,
eventtypes.LidAaPcmChange.CalculationavailableEnum.TrueVal)
self.assertEqual(ev.closedlooppreferred,
self.assertEqual(ev.closedLoopPreferred,
eventtypes.LidAaPcmChange.ClosedlooppreferredEnum.TrueVal)
def test_todict_is_json_serializable(self):
@@ -97,57 +97,57 @@ class TestLidAaUserModeChange(unittest.TestCase):
def test_stop_sleep_enums(self):
ev = Event(self.fixtureStopSleep)
self.assertEqual(ev.currentusermodeRaw, 0)
self.assertEqual(ev.currentusermode,
self.assertEqual(ev.currentUserModeRaw, 0)
self.assertEqual(ev.currentUserMode,
eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Normal)
self.assertEqual(ev.previoususermodeRaw, 1)
self.assertEqual(ev.previoususermode,
self.assertEqual(ev.previousUserModeRaw, 1)
self.assertEqual(ev.previousUserMode,
eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Sleeping)
self.assertEqual(ev.requestedactionRaw, 2)
self.assertEqual(ev.requestedaction,
self.assertEqual(ev.requestedActionRaw, 2)
self.assertEqual(ev.requestedAction,
eventtypes.LidAaUserModeChange.RequestedactionEnum.StopSleep)
def test_start_sleep_enums(self):
ev = Event(self.fixtureStartSleep)
self.assertEqual(ev.currentusermode,
self.assertEqual(ev.currentUserMode,
eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Sleeping)
self.assertEqual(ev.previoususermode,
self.assertEqual(ev.previousUserMode,
eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Normal)
self.assertEqual(ev.requestedaction,
self.assertEqual(ev.requestedAction,
eventtypes.LidAaUserModeChange.RequestedactionEnum.StartSleep)
def test_start_exercise_enums(self):
ev = Event(self.fixtureStartExercise)
self.assertEqual(ev.currentusermode,
self.assertEqual(ev.currentUserMode,
eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Exercising)
self.assertEqual(ev.previoususermode,
self.assertEqual(ev.previousUserMode,
eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Normal)
self.assertEqual(ev.requestedaction,
self.assertEqual(ev.requestedAction,
eventtypes.LidAaUserModeChange.RequestedactionEnum.StartExercise)
def test_stop_exercise_enums(self):
ev = Event(self.fixtureStopExercise)
self.assertEqual(ev.currentusermode,
self.assertEqual(ev.currentUserMode,
eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Sleeping)
self.assertEqual(ev.previoususermode,
self.assertEqual(ev.previousUserMode,
eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Exercising)
self.assertEqual(ev.requestedaction,
self.assertEqual(ev.requestedAction,
eventtypes.LidAaUserModeChange.RequestedactionEnum.StopExercise)
def test_active_sleep_schedule_single_bit(self):
# activeSleepSchedule:[0] -> 1<<0 == 1 -> SleepSchedule1IsActive
ev = Event(self.fixtureStopSleep)
self.assertEqual(ev.activesleepscheduleRaw, 1)
self.assertEqual(ev.activesleepschedule,
self.assertEqual(ev.activeSleepScheduleRaw, 1)
self.assertEqual(ev.activeSleepSchedule,
eventtypes.LidAaUserModeChange.ActivesleepscheduleBitmask.SleepSchedule1IsActive)
def test_active_sleep_schedule_empty(self):
# An empty array folds to 0 (empty IntFlag), not None.
ev = Event(self.fixtureStartExercise)
self.assertEqual(ev.activesleepscheduleRaw, 0)
self.assertEqual(ev.activesleepschedule,
self.assertEqual(ev.activeSleepScheduleRaw, 0)
self.assertEqual(ev.activeSleepSchedule,
eventtypes.LidAaUserModeChange.ActivesleepscheduleBitmask(0))
self.assertEqual(int(ev.activesleepschedule), 0)
self.assertEqual(int(ev.activeSleepSchedule), 0)
def test_todict_json_serializable(self):
for fx in (self.fixtureStopSleep, self.fixtureStartSleep,
@@ -56,23 +56,23 @@ class TestLidAlarmActivated(unittest.TestCase):
def test_alarmid_resolves_resume_pump_alarm(self):
# alarmId:18 -> RESUME_PUMP_ALARM
ev = Event(self.fixtureResumePumpAlarm)
self.assertEqual(ev.alarmidRaw, 18)
self.assertEqual(ev.alarmid, eventtypes.LidAlarmActivated.AlarmidEnum.ResumePumpAlarm)
self.assertEqual(ev.alarmIdRaw, 18)
self.assertEqual(ev.alarmId, eventtypes.LidAlarmActivated.AlarmidEnum.ResumePumpAlarm)
def test_alarmid_resolves_resume_pump_alarm2(self):
# alarmId:23 -> RESUME_PUMP_ALARM2
ev = Event(self.fixtureResumePumpAlarm2)
self.assertEqual(ev.alarmidRaw, 23)
self.assertEqual(ev.alarmid, eventtypes.LidAlarmActivated.AlarmidEnum.ResumePumpAlarm2)
self.assertEqual(ev.alarmIdRaw, 23)
self.assertEqual(ev.alarmId, eventtypes.LidAlarmActivated.AlarmidEnum.ResumePumpAlarm2)
def test_plain_fields(self):
ev = Event(self.fixtureResumePumpAlarm)
self.assertEqual(ev.faultlocatordata, 8311)
self.assertEqual(ev.faultLocatorData, 8311)
self.assertEqual(ev.param1, 3993668)
self.assertEqual(ev.param2, 0)
ev2 = Event(self.fixtureResumePumpAlarm2)
self.assertEqual(ev2.faultlocatordata, 8311)
self.assertEqual(ev2.faultLocatorData, 8311)
self.assertEqual(ev2.param1, 18)
self.assertEqual(ev2.param2, 0)
@@ -89,8 +89,8 @@ class TestLidAlarmActivated(unittest.TestCase):
"name": "LID_ALARM_ACTIVATED",
"seqNum": 398724,
"eventTimestamp": "2026-05-01T17:08:10-04:00",
"alarmidRaw": 18,
"faultlocatordata": 8311,
"alarmIdRaw": 18,
"faultLocatorData": 8311,
"param1": 3993668,
"param2": 0,
})
@@ -56,14 +56,14 @@ class TestLidAlarmCleared(unittest.TestCase):
def test_alarmid_resolves_resume_pump_alarm(self):
# alarmId:18 -> RESUME_PUMP_ALARM
ev = Event(self.fixtureResumePumpAlarm)
self.assertEqual(ev.alarmidRaw, 18)
self.assertEqual(ev.alarmid, eventtypes.LidAlarmCleared.AlarmidEnum.ResumePumpAlarm)
self.assertEqual(ev.alarmIdRaw, 18)
self.assertEqual(ev.alarmId, eventtypes.LidAlarmCleared.AlarmidEnum.ResumePumpAlarm)
def test_alarmid_resolves_resume_pump_alarm2(self):
# alarmId:23 -> RESUME_PUMP_ALARM2
ev = Event(self.fixtureResumePumpAlarm2)
self.assertEqual(ev.alarmidRaw, 23)
self.assertEqual(ev.alarmid, eventtypes.LidAlarmCleared.AlarmidEnum.ResumePumpAlarm2)
self.assertEqual(ev.alarmIdRaw, 23)
self.assertEqual(ev.alarmId, eventtypes.LidAlarmCleared.AlarmidEnum.ResumePumpAlarm2)
def test_todict_is_json_serializable(self):
for f in (self.fixtureResumePumpAlarm, self.fixtureResumePumpAlarm2):
@@ -78,7 +78,7 @@ class TestLidAlarmCleared(unittest.TestCase):
"name": "LID_ALARM_CLEARED",
"seqNum": 398734,
"eventTimestamp": "2026-05-01T17:11:22-04:00",
"alarmidRaw": 18,
"alarmIdRaw": 18,
})
@@ -95,41 +95,41 @@ class TestLidAlertActivated(unittest.TestCase):
def test_plain_fields(self):
ev = Event(self.fixtureLowInsulinFloat)
self.assertEqual(ev.faultlocatordata, 8242)
self.assertEqual(ev.faultLocatorData, 8242)
self.assertEqual(ev.param1, 102)
self.assertAlmostEqual(ev.param2, 249.76517)
ev = Event(self.fixtureIncompleteFillTubing)
self.assertEqual(ev.faultlocatordata, 8378)
self.assertEqual(ev.faultLocatorData, 8378)
self.assertEqual(ev.param1, 0)
self.assertEqual(ev.param2, 0)
def test_alertid_enum_resolves_from_raw_int(self):
ev = Event(self.fixtureDefaultAlert50)
self.assertEqual(ev.alertidRaw, 50)
self.assertEqual(ev.alertid,
self.assertEqual(ev.alertIdRaw, 50)
self.assertEqual(ev.alertId,
eventtypes.LidAlertActivated.AlertidEnum.DefaultAlert50)
ev = Event(self.fixtureControlIqLow)
self.assertEqual(ev.alertidRaw, 51)
self.assertEqual(ev.alertid,
self.assertEqual(ev.alertIdRaw, 51)
self.assertEqual(ev.alertId,
eventtypes.LidAlertActivated.AlertidEnum.ControlIqLow)
ev = Event(self.fixtureIncompleteFillTubing)
self.assertEqual(ev.alertidRaw, 14)
self.assertEqual(ev.alertid,
self.assertEqual(ev.alertIdRaw, 14)
self.assertEqual(ev.alertId,
eventtypes.LidAlertActivated.AlertidEnum.IncompleteFillTubingAlert)
ev = Event(self.fixtureLowPower)
self.assertEqual(ev.alertidRaw, 2)
self.assertEqual(ev.alertid,
self.assertEqual(ev.alertIdRaw, 2)
self.assertEqual(ev.alertId,
eventtypes.LidAlertActivated.AlertidEnum.LowPowerAlert)
def test_alertid_zero_value_resolves(self):
# alertId:0 -> LowInsulinAlert (0 must not be treated as missing).
ev = Event(self.fixtureLowInsulinFloat)
self.assertEqual(ev.alertidRaw, 0)
self.assertEqual(ev.alertid,
self.assertEqual(ev.alertIdRaw, 0)
self.assertEqual(ev.alertId,
eventtypes.LidAlertActivated.AlertidEnum.LowInsulinAlert)
def test_todict_is_json_serializable(self):
@@ -145,8 +145,8 @@ class TestLidAlertActivated(unittest.TestCase):
ev = Event(self.fixtureLowInsulinFloat)
d = ev.todict()
self.assertEqual(d["seqNum"], 398333)
self.assertEqual(d["alertidRaw"], 0)
self.assertEqual(d["faultlocatordata"], 8242)
self.assertEqual(d["alertIdRaw"], 0)
self.assertEqual(d["faultLocatorData"], 8242)
self.assertEqual(d["param1"], 102)
self.assertAlmostEqual(d["param2"], 249.76517)
@@ -75,27 +75,27 @@ class TestLidAlertCleared(unittest.TestCase):
def test_plain_field_round_trips(self):
ev = Event(self.fixtureControlIqLow)
self.assertEqual(ev.faultlocatordata, 0)
self.assertEqual(ev.faultLocatorData, 0)
def test_alertid_raw_round_trips(self):
self.assertEqual(Event(self.fixtureLowInsulin).alertidRaw, 0)
self.assertEqual(Event(self.fixtureLowPower).alertidRaw, 2)
self.assertEqual(Event(self.fixtureIncompleteFillTubing).alertidRaw, 14)
self.assertEqual(Event(self.fixtureControlIqLow).alertidRaw, 51)
self.assertEqual(Event(self.fixtureLowInsulin).alertIdRaw, 0)
self.assertEqual(Event(self.fixtureLowPower).alertIdRaw, 2)
self.assertEqual(Event(self.fixtureIncompleteFillTubing).alertIdRaw, 14)
self.assertEqual(Event(self.fixtureControlIqLow).alertIdRaw, 51)
def test_alertid_resolves_to_enum(self):
E = eventtypes.LidAlertCleared.AlertidEnum
self.assertEqual(Event(self.fixtureLowInsulin).alertid, E.LowInsulinAlert)
self.assertEqual(Event(self.fixtureLowPower).alertid, E.LowPowerAlert)
self.assertEqual(Event(self.fixtureIncompleteFillTubing).alertid,
self.assertEqual(Event(self.fixtureLowInsulin).alertId, E.LowInsulinAlert)
self.assertEqual(Event(self.fixtureLowPower).alertId, E.LowPowerAlert)
self.assertEqual(Event(self.fixtureIncompleteFillTubing).alertId,
E.IncompleteFillTubingAlert)
self.assertEqual(Event(self.fixtureControlIqLow).alertid, E.ControlIqLow)
self.assertEqual(Event(self.fixtureControlIqLow).alertId, E.ControlIqLow)
def test_alertid_zero_resolves(self):
# alertId 0 must resolve, not be dropped as a falsy/missing value.
ev = Event(self.fixtureLowInsulin)
self.assertEqual(ev.alertidRaw, 0)
self.assertEqual(ev.alertid,
self.assertEqual(ev.alertIdRaw, 0)
self.assertEqual(ev.alertId,
eventtypes.LidAlertCleared.AlertidEnum.LowInsulinAlert)
def test_todict_is_json_serializable(self):
@@ -105,8 +105,8 @@ class TestLidAlertCleared(unittest.TestCase):
self.assertEqual(d["id"], 26)
self.assertEqual(d["name"], "LID_ALERT_CLEARED")
self.assertEqual(d["seqNum"], 396276)
self.assertEqual(d["alertidRaw"], 51)
self.assertEqual(d["faultlocatordata"], 0)
self.assertEqual(d["alertIdRaw"], 51)
self.assertEqual(d["faultLocatorData"], 0)
if __name__ == "__main__":
@@ -58,51 +58,51 @@ class TestLidBgReadingTaken(unittest.TestCase):
def test_bg_iob_targetbg_isf_round_trip(self):
ev = Event(self.fixtureManualEntry)
self.assertEqual(ev.BG, 151)
self.assertAlmostEqual(ev.IOB, 1.1809407)
self.assertEqual(ev.targetbg, 110)
self.assertEqual(ev.ISF, 30)
self.assertEqual(ev.bg, 151)
self.assertAlmostEqual(ev.iob, 1.1809407)
self.assertEqual(ev.targetBg, 110)
self.assertEqual(ev.isf, 30)
ev2 = Event(self.fixtureAutoPopulated)
self.assertEqual(ev2.BG, 164)
self.assertAlmostEqual(ev2.IOB, 1.8189592)
self.assertEqual(ev2.targetbg, 110)
self.assertEqual(ev2.ISF, 30)
self.assertEqual(ev2.bg, 164)
self.assertAlmostEqual(ev2.iob, 1.8189592)
self.assertEqual(ev2.targetBg, 110)
self.assertEqual(ev2.isf, 30)
def test_selectediob_enum_resolves(self):
# selectedIob:1 -> SwanIobMeal
ev = Event(self.fixtureManualEntry)
self.assertEqual(ev.selectediobRaw, 1)
self.assertEqual(ev.selectediob,
self.assertEqual(ev.selectedIobRaw, 1)
self.assertEqual(ev.selectedIob,
eventtypes.LidBgReadingTaken.SelectediobEnum.SwanIobMeal)
def test_bgentrytype_enum_resolves(self):
# bgEntryType:0 -> ManualEntryByTheUserViaNumpad (0 not treated as missing)
ev = Event(self.fixtureManualEntry)
self.assertEqual(ev.bgentrytypeRaw, 0)
self.assertEqual(ev.bgEntryTypeRaw, 0)
self.assertEqual(
ev.bgentrytype,
ev.bgEntryType,
eventtypes.LidBgReadingTaken.BgentrytypeEnum.ManualEntryByTheUserViaNumpad)
# bgEntryType:1 -> AutoPopulatedBgUsingDexcomEgv
ev2 = Event(self.fixtureAutoPopulated)
self.assertEqual(ev2.bgentrytypeRaw, 1)
self.assertEqual(ev2.bgEntryTypeRaw, 1)
self.assertEqual(
ev2.bgentrytype,
ev2.bgEntryType,
eventtypes.LidBgReadingTaken.BgentrytypeEnum.AutoPopulatedBgUsingDexcomEgv)
def test_bgsourcetype_enum_resolves(self):
# bgSourceType:1 -> RemoteEntry
ev = Event(self.fixtureManualEntry)
self.assertEqual(ev.bgsourcetypeRaw, 1)
self.assertEqual(ev.bgsourcetype,
self.assertEqual(ev.bgSourceTypeRaw, 1)
self.assertEqual(ev.bgSourceType,
eventtypes.LidBgReadingTaken.BgsourcetypeEnum.RemoteEntry)
def test_cgmcalibration_enum_resolves(self):
# cgmCalibration:0 -> No (0 not treated as missing)
ev = Event(self.fixtureManualEntry)
self.assertEqual(ev.cgmcalibrationRaw, 0)
self.assertEqual(ev.cgmcalibration,
self.assertEqual(ev.cgmCalibrationRaw, 0)
self.assertEqual(ev.cgmCalibration,
eventtypes.LidBgReadingTaken.CgmcalibrationEnum.No)
def test_todict_is_json_serializable(self):
@@ -69,28 +69,28 @@ class TestLidBolusActivated(unittest.TestCase):
def test_bolus_fields_round_trip(self):
ev = Event(self.fixtureMeal)
self.assertEqual(ev.bolusid, 1423)
self.assertAlmostEqual(ev.IOB, 1.8189592)
self.assertAlmostEqual(ev.bolussize, 8.33)
self.assertEqual(ev.bolusId, 1423)
self.assertAlmostEqual(ev.iob, 1.8189592)
self.assertAlmostEqual(ev.bolusSize, 8.33)
def test_zero_iob_is_preserved(self):
# iob:0 must not be dropped as missing.
ev = Event(self.fixtureZeroIob)
self.assertEqual(ev.bolusid, 1426)
self.assertEqual(ev.IOB, 0)
self.assertAlmostEqual(ev.bolussize, 10.96)
self.assertEqual(ev.bolusId, 1426)
self.assertEqual(ev.iob, 0)
self.assertAlmostEqual(ev.bolusSize, 10.96)
def test_small_bolus_round_trips(self):
ev = Event(self.fixtureSmall)
self.assertEqual(ev.bolusid, 1425)
self.assertAlmostEqual(ev.IOB, 4.116488)
self.assertEqual(ev.bolussize, 2)
self.assertEqual(ev.bolusId, 1425)
self.assertAlmostEqual(ev.iob, 4.116488)
self.assertEqual(ev.bolusSize, 2)
def test_selectediob_resolves_to_enum(self):
# selectedIob:1 -> Swan IOB Meal
ev = Event(self.fixtureMeal)
self.assertEqual(ev.selectediobRaw, 1)
self.assertEqual(ev.selectediob,
self.assertEqual(ev.selectedIobRaw, 1)
self.assertEqual(ev.selectedIob,
eventtypes.LidBolusActivated.SelectediobEnum.SwanIobMeal)
def test_spareA3_is_ignored(self):
@@ -55,29 +55,29 @@ class TestLidBolusCompleted(unittest.TestCase):
def test_completed_fields_round_trip(self):
ev = Event(self.fixtureCompleted)
self.assertEqual(ev.bolusid, 1423)
self.assertAlmostEqual(ev.insulindelivered, 8.33)
self.assertAlmostEqual(ev.insulinrequested, 8.33)
self.assertAlmostEqual(ev.IOB, 10.088287)
self.assertEqual(ev.bolusId, 1423)
self.assertAlmostEqual(ev.insulinDelivered, 8.33)
self.assertAlmostEqual(ev.insulinRequested, 8.33)
self.assertAlmostEqual(ev.iob, 10.088287)
def test_interrupted_fields_round_trip(self):
ev = Event(self.fixtureInterrupted)
self.assertEqual(ev.bolusid, 1644)
self.assertAlmostEqual(ev.insulindelivered, 0.04657)
self.assertAlmostEqual(ev.insulinrequested, 0.5)
self.assertAlmostEqual(ev.IOB, 1.2275107)
self.assertEqual(ev.bolusId, 1644)
self.assertAlmostEqual(ev.insulinDelivered, 0.04657)
self.assertAlmostEqual(ev.insulinRequested, 0.5)
self.assertAlmostEqual(ev.iob, 1.2275107)
# Interrupted: less insulin delivered than requested.
self.assertLess(ev.insulindelivered, ev.insulinrequested)
self.assertLess(ev.insulinDelivered, ev.insulinRequested)
def test_completionstatus_resolves_to_enum(self):
completed = Event(self.fixtureCompleted)
self.assertEqual(completed.completionstatusRaw, 3)
self.assertEqual(completed.completionstatus,
self.assertEqual(completed.completionStatusRaw, 3)
self.assertEqual(completed.completionStatus,
eventtypes.LidBolusCompleted.CompletionstatusEnum.Completed)
interrupted = Event(self.fixtureInterrupted)
self.assertEqual(interrupted.completionstatusRaw, 0)
self.assertEqual(interrupted.completionstatus,
self.assertEqual(interrupted.completionStatusRaw, 0)
self.assertEqual(interrupted.completionStatus,
eventtypes.LidBolusCompleted.CompletionstatusEnum.UserAborted)
def test_todict_is_json_serializable(self):
@@ -78,7 +78,7 @@ class TestLidBolusDelivery(unittest.TestCase):
def test_plain_fields_round_trip(self):
ev = Event(self.fixtureCarbCorrectionStarted)
self.assertEqual(ev.bolusid, 1426)
self.assertEqual(ev.bolusId, 1426)
self.assertEqual(ev.requestedNow, 10960)
self.assertEqual(ev.deliveredTotal, 0)
self.assertEqual(ev.correction, 130)
@@ -88,7 +88,7 @@ class TestLidBolusDelivery(unittest.TestCase):
def test_completion_carries_delivered_total(self):
ev = Event(self.fixtureCarbCorrectionCompleted)
self.assertEqual(ev.bolusid, 1426)
self.assertEqual(ev.bolusId, 1426)
self.assertEqual(ev.deliveredTotal, 10960)
def test_bolustype_single_bit_folds_and_resolves(self):
@@ -63,50 +63,50 @@ class TestLidBolusRequestedMsg1(unittest.TestCase):
def test_plain_fields_round_trip(self):
ev = Event(self.fixtureRemoteWithCarbs)
self.assertEqual(ev.bolusid, 1423)
self.assertEqual(ev.carbamount, 50)
self.assertEqual(ev.BG, 164)
self.assertEqual(ev.IOB, 1.82)
self.assertEqual(ev.bolusId, 1423)
self.assertEqual(ev.carbAmount, 50)
self.assertEqual(ev.bg, 164)
self.assertEqual(ev.iob, 1.82)
def test_fractional_iob_and_zero_bg(self):
ev = Event(self.fixtureInsulinNoCarbs)
self.assertEqual(ev.bolusid, 1425)
self.assertEqual(ev.carbamount, 0)
self.assertEqual(ev.BG, 0)
self.assertAlmostEqual(ev.IOB, 4.116488)
self.assertEqual(ev.bolusId, 1425)
self.assertEqual(ev.carbAmount, 0)
self.assertEqual(ev.bg, 0)
self.assertAlmostEqual(ev.iob, 4.116488)
def test_bolustype_remote(self):
ev = Event(self.fixtureRemoteWithCarbs)
self.assertEqual(ev.bolustypeRaw, 3)
self.assertEqual(ev.bolustype,
self.assertEqual(ev.bolusTypeRaw, 3)
self.assertEqual(ev.bolusType,
eventtypes.LidBolusRequestedMsg1.BolustypeEnum.Remote)
def test_bolustype_insulin(self):
# bolusType 0 must resolve (0 not treated as missing).
ev = Event(self.fixtureInsulinNoCarbs)
self.assertEqual(ev.bolustypeRaw, 0)
self.assertEqual(ev.bolustype,
self.assertEqual(ev.bolusTypeRaw, 0)
self.assertEqual(ev.bolusType,
eventtypes.LidBolusRequestedMsg1.BolustypeEnum.Insulin)
def test_correctionbolusincluded_no(self):
ev = Event(self.fixtureRemoteWithCarbs)
self.assertEqual(ev.correctionbolusincludedRaw, 0)
self.assertEqual(ev.correctionBolusIncludedRaw, 0)
self.assertEqual(
ev.correctionbolusincluded,
ev.correctionBolusIncluded,
eventtypes.LidBolusRequestedMsg1.CorrectionbolusincludedEnum.No)
def test_correctionbolusincluded_yes(self):
ev = Event(self.fixtureRemoteWithCorrection)
self.assertEqual(ev.correctionbolusincludedRaw, 1)
self.assertEqual(ev.correctionBolusIncludedRaw, 1)
self.assertEqual(
ev.correctionbolusincluded,
ev.correctionBolusIncluded,
eventtypes.LidBolusRequestedMsg1.CorrectionbolusincludedEnum.Yes)
def test_carbratio_scales(self):
# carbratio is carbratioRaw * 0.001; real captures carry 0.
ev = Event(self.fixtureRemoteWithCorrection)
self.assertEqual(ev.carbratioRaw, 0)
self.assertAlmostEqual(ev.carbratio, 0.0)
self.assertEqual(ev.carbRatioRaw, 0)
self.assertAlmostEqual(ev.carbRatio, 0.0)
def test_todict_is_json_serializable(self):
for fixture in (self.fixtureRemoteWithCarbs,
@@ -117,7 +117,7 @@ class TestLidBolusRequestedMsg1(unittest.TestCase):
json.dumps(d) # must not raise
self.assertEqual(d["id"], 64)
self.assertEqual(d["name"], "LID_BOLUS_REQUESTED_MSG1")
self.assertEqual(d["bolusid"],
self.assertEqual(d["bolusId"],
fixture["eventProperties"]["bolusId"])
@@ -72,11 +72,11 @@ class TestLidBolusRequestedMsg2(unittest.TestCase):
def test_plain_fields_round_trip(self):
ev = Event(self.fixtureBleStandard)
self.assertEqual(ev.bolusid, 1423)
self.assertEqual(ev.standardpercent, 100)
self.assertEqual(ev.bolusId, 1423)
self.assertEqual(ev.standardPercent, 100)
self.assertEqual(ev.duration, 0)
self.assertEqual(ev.ISF, 0)
self.assertEqual(ev.targetbg, 0)
self.assertEqual(ev.isf, 0)
self.assertEqual(ev.targetBg, 0)
def test_options_enum_ble_standard(self):
ev = Event(self.fixtureBleStandard)
@@ -92,26 +92,26 @@ class TestLidBolusRequestedMsg2(unittest.TestCase):
def test_selectediob_enum(self):
ev = Event(self.fixtureBleStandard)
self.assertEqual(ev.selectediobRaw, 1)
self.assertEqual(ev.selectediob,
self.assertEqual(ev.selectedIobRaw, 1)
self.assertEqual(ev.selectedIob,
eventtypes.LidBolusRequestedMsg2.SelectediobEnum.SwanIobMeal)
def test_useroverride_enum_no(self):
ev = Event(self.fixtureBleStandard)
self.assertEqual(ev.useroverrideRaw, 0)
self.assertEqual(ev.useroverride,
self.assertEqual(ev.userOverrideRaw, 0)
self.assertEqual(ev.userOverride,
eventtypes.LidBolusRequestedMsg2.UseroverrideEnum.No)
def test_useroverride_enum_yes(self):
ev = Event(self.fixtureUserOverride)
self.assertEqual(ev.useroverrideRaw, 1)
self.assertEqual(ev.useroverride,
self.assertEqual(ev.userOverrideRaw, 1)
self.assertEqual(ev.userOverride,
eventtypes.LidBolusRequestedMsg2.UseroverrideEnum.Yes)
def test_declinedcorrection_enum(self):
ev = Event(self.fixtureBleStandard)
self.assertEqual(ev.declinedcorrectionRaw, 0)
self.assertEqual(ev.declinedcorrection,
self.assertEqual(ev.declinedCorrectionRaw, 0)
self.assertEqual(ev.declinedCorrection,
eventtypes.LidBolusRequestedMsg2.DeclinedcorrectionEnum.No)
def test_todict_is_json_serializable(self):
@@ -87,31 +87,31 @@ class TestLidBolusRequestedMsg3(unittest.TestCase):
def test_food_only(self):
ev = Event(self.fixtureFoodOnly)
self.assertEqual(ev.bolusid, 1423)
self.assertAlmostEqual(ev.foodbolussize, 8.33)
self.assertAlmostEqual(ev.correctionbolussize, 0)
self.assertAlmostEqual(ev.totalbolussize, 8.330001)
self.assertEqual(ev.bolusId, 1423)
self.assertAlmostEqual(ev.foodBolusSize, 8.33)
self.assertAlmostEqual(ev.correctionBolusSize, 0)
self.assertAlmostEqual(ev.totalBolusSize, 8.330001)
def test_food_and_correction(self):
ev = Event(self.fixtureFoodAndCorrection)
self.assertEqual(ev.bolusid, 1426)
self.assertAlmostEqual(ev.foodbolussize, 10.83)
self.assertAlmostEqual(ev.correctionbolussize, 0.13)
self.assertAlmostEqual(ev.totalbolussize, 10.96)
self.assertEqual(ev.bolusId, 1426)
self.assertAlmostEqual(ev.foodBolusSize, 10.83)
self.assertAlmostEqual(ev.correctionBolusSize, 0.13)
self.assertAlmostEqual(ev.totalBolusSize, 10.96)
def test_correction_only(self):
ev = Event(self.fixtureCorrectionOnly)
self.assertEqual(ev.bolusid, 1430)
self.assertAlmostEqual(ev.foodbolussize, 0)
self.assertAlmostEqual(ev.correctionbolussize, 1.47)
self.assertAlmostEqual(ev.totalbolussize, 3)
self.assertEqual(ev.bolusId, 1430)
self.assertAlmostEqual(ev.foodBolusSize, 0)
self.assertAlmostEqual(ev.correctionBolusSize, 1.47)
self.assertAlmostEqual(ev.totalBolusSize, 3)
def test_total_only(self):
ev = Event(self.fixtureTotalOnly)
self.assertEqual(ev.bolusid, 1424)
self.assertAlmostEqual(ev.foodbolussize, 0)
self.assertAlmostEqual(ev.correctionbolussize, 0)
self.assertAlmostEqual(ev.totalbolussize, 4)
self.assertEqual(ev.bolusId, 1424)
self.assertAlmostEqual(ev.foodBolusSize, 0)
self.assertAlmostEqual(ev.correctionBolusSize, 0)
self.assertAlmostEqual(ev.totalBolusSize, 4)
def test_todict_json_serializable(self):
for fixture in (self.fixtureFoodOnly, self.fixtureFoodAndCorrection,
@@ -42,13 +42,13 @@ class TestLidCannulaFilled(unittest.TestCase):
def test_primesize_round_trips(self):
ev = Event(self.fixtureCompleted)
self.assertEqual(ev.primesize, 0.3)
self.assertEqual(ev.primeSize, 0.3)
def test_completionstatus_resolves_to_enum(self):
# completionStatus:3 -> Completed
ev = Event(self.fixtureCompleted)
self.assertEqual(ev.completionstatusRaw, 3)
self.assertEqual(ev.completionstatus,
self.assertEqual(ev.completionStatusRaw, 3)
self.assertEqual(ev.completionStatus,
eventtypes.LidCannulaFilled.CompletionstatusEnum.Completed)
def test_unknown_infusionsettype_key_is_ignored(self):
@@ -59,9 +59,9 @@ class TestLidCartridgeFilled(unittest.TestCase):
"2026-04-30T10:16:09")
def test_insulinvolume_round_trips(self):
self.assertEqual(Event(self.fixtureMin).insulinvolume, 60)
self.assertEqual(Event(self.fixtureMid).insulinvolume, 105)
self.assertEqual(Event(self.fixtureMax).insulinvolume, 190)
self.assertEqual(Event(self.fixtureMin).insulinVolume, 60)
self.assertEqual(Event(self.fixtureMid).insulinVolume, 105)
self.assertEqual(Event(self.fixtureMax).insulinVolume, 190)
def test_v2volume_round_trips(self):
for fixture in (self.fixtureMin, self.fixtureMid, self.fixtureMax):
@@ -77,7 +77,7 @@ class TestLidCartridgeFilled(unittest.TestCase):
def test_todict_reflects_real_values(self):
d = Event(self.fixtureMax).todict()
self.assertEqual(d["seqNum"], 463083)
self.assertEqual(d["insulinvolume"], 190)
self.assertEqual(d["insulinVolume"], 190)
self.assertEqual(d["v2Volume"], 0)
@@ -58,29 +58,29 @@ class TestLidCgmAlertAckDex(unittest.TestCase):
def test_dalertid_resolves_cgm_high(self):
ev = Event(self.fixtureCgmHigh)
self.assertEqual(ev.dalertidRaw, 2)
self.assertEqual(ev.dalertid, eventtypes.LidCgmAlertAckDex.DalertidEnum.CgmHigh)
self.assertEqual(ev.dalertIdRaw, 2)
self.assertEqual(ev.dalertId, eventtypes.LidCgmAlertAckDex.DalertidEnum.CgmHigh)
def test_dalertid_resolves_sensor_expiring_soon(self):
ev = Event(self.fixtureSensorExpiringSoon)
self.assertEqual(ev.dalertidRaw, 12)
self.assertEqual(ev.dalertid, eventtypes.LidCgmAlertAckDex.DalertidEnum.CgmSensorExpiringSoon)
self.assertEqual(ev.dalertIdRaw, 12)
self.assertEqual(ev.dalertId, eventtypes.LidCgmAlertAckDex.DalertidEnum.CgmSensorExpiringSoon)
def test_sensortype_resolves_g7(self):
for fx in (self.fixtureCgmHigh, self.fixtureSensorExpiringSoon, self.fixtureAckBySoftware):
ev = Event(fx)
self.assertEqual(ev.sensortypeRaw, 3)
self.assertEqual(ev.sensortype, eventtypes.LidCgmAlertAckDex.SensortypeEnum.CgmTypeDexcomG7)
self.assertEqual(ev.sensorTypeRaw, 3)
self.assertEqual(ev.sensorType, eventtypes.LidCgmAlertAckDex.SensortypeEnum.CgmTypeDexcomG7)
def test_acksource_resolves_by_user(self):
ev = Event(self.fixtureCgmHigh)
self.assertEqual(ev.acksourceRaw, 0)
self.assertEqual(ev.acksource, eventtypes.LidCgmAlertAckDex.AcksourceEnum.AlertAcknowledgedByUser)
self.assertEqual(ev.ackSourceRaw, 0)
self.assertEqual(ev.ackSource, eventtypes.LidCgmAlertAckDex.AcksourceEnum.AlertAcknowledgedByUser)
def test_acksource_resolves_by_software(self):
ev = Event(self.fixtureAckBySoftware)
self.assertEqual(ev.acksourceRaw, 1)
self.assertEqual(ev.acksource, eventtypes.LidCgmAlertAckDex.AcksourceEnum.AlertAcknowledgedBySoftware)
self.assertEqual(ev.ackSourceRaw, 1)
self.assertEqual(ev.ackSource, eventtypes.LidCgmAlertAckDex.AcksourceEnum.AlertAcknowledgedBySoftware)
def test_todict_is_json_serializable(self):
for fx in (self.fixtureCgmHigh, self.fixtureSensorExpiringSoon, self.fixtureAckBySoftware):
@@ -89,7 +89,7 @@ class TestLidCgmAlertActivatedDex(unittest.TestCase):
def test_plain_fields_round_trip(self):
ev = Event(self.fixtureOutOfRange)
self.assertEqual(ev.faultlocatordata, 8462)
self.assertEqual(ev.faultLocatorData, 8462)
self.assertEqual(ev.param1, 25)
self.assertEqual(ev.param2, 917)
@@ -103,16 +103,16 @@ class TestLidCgmAlertActivatedDex(unittest.TestCase):
]
for f, raw, member in cases:
ev = Event(f)
self.assertEqual(ev.dalertidRaw, raw)
self.assertEqual(ev.dalertid, member)
self.assertEqual(ev.dalertIdRaw, raw)
self.assertEqual(ev.dalertId, member)
def test_sensortype_enum_resolves(self):
# every capture is sensorType:3 -> Dexcom G7
for f in (self.fixtureHigh, self.fixtureLow, self.fixtureFixedLow,
self.fixtureOutOfRange, self.fixtureSensorFail):
ev = Event(f)
self.assertEqual(ev.sensortypeRaw, 3)
self.assertEqual(ev.sensortype,
self.assertEqual(ev.sensorTypeRaw, 3)
self.assertEqual(ev.sensorType,
eventtypes.LidCgmAlertActivatedDex.SensortypeEnum.CgmTypeDexcomG7)
def test_todict_is_json_serializable(self):
@@ -58,22 +58,22 @@ class TestLidCgmAlertClearedDex(unittest.TestCase):
"2026-05-01T17:18:01")
def test_dalertid_resolves_to_enum(self):
self.assertEqual(Event(self.fixtureCgmLow).dalertidRaw, 3)
self.assertEqual(Event(self.fixtureCgmLow).dalertid,
self.assertEqual(Event(self.fixtureCgmLow).dalertIdRaw, 3)
self.assertEqual(Event(self.fixtureCgmLow).dalertId,
eventtypes.LidCgmAlertClearedDex.DalertidEnum.CgmLow)
self.assertEqual(Event(self.fixtureCgmFixedLow).dalertidRaw, 1)
self.assertEqual(Event(self.fixtureCgmFixedLow).dalertid,
self.assertEqual(Event(self.fixtureCgmFixedLow).dalertIdRaw, 1)
self.assertEqual(Event(self.fixtureCgmFixedLow).dalertId,
eventtypes.LidCgmAlertClearedDex.DalertidEnum.CgmFixedLow)
self.assertEqual(Event(self.fixtureCgmOutOfRange).dalertidRaw, 14)
self.assertEqual(Event(self.fixtureCgmOutOfRange).dalertid,
self.assertEqual(Event(self.fixtureCgmOutOfRange).dalertIdRaw, 14)
self.assertEqual(Event(self.fixtureCgmOutOfRange).dalertId,
eventtypes.LidCgmAlertClearedDex.DalertidEnum.CgmOutOfRange)
def test_sensortype_resolves_to_enum(self):
ev = Event(self.fixtureCgmLow)
self.assertEqual(ev.sensortypeRaw, 3)
self.assertEqual(ev.sensortype,
self.assertEqual(ev.sensorTypeRaw, 3)
self.assertEqual(ev.sensorType,
eventtypes.LidCgmAlertClearedDex.SensortypeEnum.CgmTypeDexcomG7)
def test_todict_is_json_serializable(self):
@@ -83,8 +83,8 @@ class TestLidCgmAlertClearedDex(unittest.TestCase):
self.assertEqual(d["id"], 370)
self.assertEqual(d["name"], "LID_CGM_ALERT_CLEARED_DEX")
self.assertEqual(d["seqNum"], 409147)
self.assertEqual(d["dalertidRaw"], 14)
self.assertEqual(d["sensortypeRaw"], 3)
self.assertEqual(d["dalertIdRaw"], 14)
self.assertEqual(d["sensorTypeRaw"], 3)
if __name__ == "__main__":
+16 -16
View File
@@ -82,27 +82,27 @@ class TestLidCgmDataG7(unittest.TestCase):
def test_display_value_and_rssi_round_trip(self):
ev = Event(self.fixtureRising)
self.assertEqual(ev.currentglucosedisplayvalue, 287)
self.assertEqual(ev.RSSI, -87)
self.assertEqual(ev.currentGlucoseDisplayValue, 287)
self.assertEqual(ev.rssi, -87)
low = Event(self.fixtureSpecialLow)
self.assertEqual(low.currentglucosedisplayvalue, 31)
self.assertEqual(low.RSSI, -55)
self.assertEqual(low.currentGlucoseDisplayValue, 31)
self.assertEqual(low.rssi, -55)
high = Event(self.fixtureBackfill)
self.assertEqual(high.currentglucosedisplayvalue, 380)
self.assertEqual(high.RSSI, -83)
self.assertEqual(high.currentGlucoseDisplayValue, 380)
self.assertEqual(high.rssi, -83)
def test_glucosevaluestatus_enum_resolves(self):
# 0 -> PreciseValue: the zero value must resolve, not be treated as missing.
ev = Event(self.fixtureRising)
self.assertEqual(ev.glucosevaluestatusRaw, 0)
self.assertEqual(ev.glucosevaluestatus,
self.assertEqual(ev.glucoseValueStatusRaw, 0)
self.assertEqual(ev.glucoseValueStatus,
eventtypes.LidCgmDataG7.GlucosevaluestatusEnum.PreciseValue)
# 2 -> SpecialLow
low = Event(self.fixtureSpecialLow)
self.assertEqual(low.glucosevaluestatusRaw, 2)
self.assertEqual(low.glucosevaluestatus,
self.assertEqual(low.glucoseValueStatusRaw, 2)
self.assertEqual(low.glucoseValueStatus,
eventtypes.LidCgmDataG7.GlucosevaluestatusEnum.SpecialLow)
def test_algorithmstate_enum_resolves(self):
@@ -110,8 +110,8 @@ class TestLidCgmDataG7(unittest.TestCase):
for fx in (self.fixtureRising, self.fixtureFalling,
self.fixtureSpecialLow, self.fixtureBackfill):
ev = Event(fx)
self.assertEqual(ev.algorithmstateRaw, 32)
self.assertEqual(ev.algorithmstate,
self.assertEqual(ev.algorithmStateRaw, 32)
self.assertEqual(ev.algorithmState,
eventtypes.LidCgmDataG7.AlgorithmstateEnum.ReportablePeriodValidEgv)
def test_cgm_datatype_bitmask_folds_to_raw_int(self):
@@ -154,10 +154,10 @@ class TestLidCgmDataG7(unittest.TestCase):
def test_egv_timestamp_is_raw_seconds(self):
# egvTimeStamp (camelCase) normalizes onto egvTimestamp, kept as raw seconds int.
self.assertEqual(Event(self.fixtureRising).egvTimestamp, 580133707)
self.assertEqual(Event(self.fixtureFalling).egvTimestamp, 578964361)
self.assertEqual(Event(self.fixtureSpecialLow).egvTimestamp, 579800690)
self.assertEqual(Event(self.fixtureBackfill).egvTimestamp, 580602548)
self.assertEqual(Event(self.fixtureRising).egvTimeStamp, 580133707)
self.assertEqual(Event(self.fixtureFalling).egvTimeStamp, 578964361)
self.assertEqual(Event(self.fixtureSpecialLow).egvTimeStamp, 579800690)
self.assertEqual(Event(self.fixtureBackfill).egvTimeStamp, 580602548)
def test_todict_json_serializable(self):
for fx in (self.fixtureRising, self.fixtureFalling,
@@ -59,22 +59,22 @@ class TestLidCgmJoinSessionG7(unittest.TestCase):
def test_plain_fields_round_trip(self):
ev = Event(self.fixtureLowCgmTs)
self.assertEqual(ev.cgmtimestamp, 3042)
self.assertEqual(ev.sessionsignature, 72)
self.assertEqual(ev.cgmTimestamp, 3042)
self.assertEqual(ev.sessionSignature, 72)
def test_high_cgm_timestamp_fixture(self):
ev = Event(self.fixtureHighCgmTs)
self.assertEqual(ev.eventId, 394)
self.assertEqual(ev.seqNum, 449825)
self.assertEqual(ev.cgmtimestamp, 51767)
self.assertEqual(ev.sessionsignature, 117)
self.assertEqual(ev.cgmTimestamp, 51767)
self.assertEqual(ev.sessionSignature, 117)
def test_shared_signature_fixture(self):
# Same sessionSignature as the high-cgm fixture but a distinct cgmTimestamp.
ev = Event(self.fixtureSharedSignature)
self.assertEqual(ev.seqNum, 481763)
self.assertEqual(ev.cgmtimestamp, 248)
self.assertEqual(ev.sessionsignature, 117)
self.assertEqual(ev.cgmTimestamp, 248)
self.assertEqual(ev.sessionSignature, 117)
def test_todict_is_json_serializable(self):
ev = Event(self.fixtureLowCgmTs)
@@ -83,8 +83,8 @@ class TestLidCgmJoinSessionG7(unittest.TestCase):
self.assertEqual(d["id"], 394)
self.assertEqual(d["name"], "LID_CGM_JOIN_SESSION_G7")
self.assertEqual(d["seqNum"], 413856)
self.assertEqual(d["cgmtimestamp"], 3042)
self.assertEqual(d["sessionsignature"], 72)
self.assertEqual(d["cgmTimestamp"], 3042)
self.assertEqual(d["sessionSignature"], 72)
if __name__ == "__main__":
@@ -73,26 +73,26 @@ class TestLidCgmStopSessionG7(unittest.TestCase):
def test_session_time_fields_round_trip(self):
ev = Event(self.fixtureReason5)
self.assertEqual(ev.currenttransmittertime, 890598)
self.assertEqual(ev.sessionstarttime, 73)
self.assertEqual(ev.sessionstoptime, 890591)
self.assertEqual(ev.sessionduration, 10)
self.assertEqual(ev.stopsessioncode, 1)
self.assertEqual(ev.currentTransmitterTime, 890598)
self.assertEqual(ev.sessionStartTime, 73)
self.assertEqual(ev.sessionStopTime, 890591)
self.assertEqual(ev.sessionDuration, 10)
self.assertEqual(ev.stopSessionCode, 1)
def test_session_start_time_sentinel_round_trips(self):
# UINT32-max sentinel must survive as-is.
ev = Event(self.fixtureReason15)
self.assertEqual(ev.sessionstarttime, 4294967295)
self.assertEqual(ev.sessionstoptime, 0)
self.assertEqual(ev.stopsessioncode, 0)
self.assertEqual(ev.sessionStartTime, 4294967295)
self.assertEqual(ev.sessionStopTime, 0)
self.assertEqual(ev.stopSessionCode, 0)
def test_session_stop_reason_is_raw_int(self):
# No enum is generated for sessionStopReason; it stays the captured int.
self.assertFalse(hasattr(eventtypes.LidCgmStopSessionG7,
"SessionstopreasonEnum"))
self.assertEqual(Event(self.fixtureReason5).sessionstopreason, 5)
self.assertEqual(Event(self.fixtureReason16).sessionstopreason, 16)
self.assertEqual(Event(self.fixtureReason15).sessionstopreason, 15)
self.assertEqual(Event(self.fixtureReason5).sessionStopReason, 5)
self.assertEqual(Event(self.fixtureReason16).sessionStopReason, 16)
self.assertEqual(Event(self.fixtureReason15).sessionStopReason, 15)
def test_todict_is_json_serializable(self):
for fixture in (self.fixtureReason5, self.fixtureReason16,
@@ -102,7 +102,7 @@ class TestLidCgmStopSessionG7(unittest.TestCase):
self.assertEqual(d["id"], 447)
self.assertEqual(d["name"], "LID_CGM_STOP_SESSION_G7")
self.assertEqual(
d["sessionstopreason"],
d["sessionStopReason"],
fixture["eventProperties"]["sessionStopReason"])
+12 -12
View File
@@ -62,21 +62,21 @@ class TestLidDateChanged(unittest.TestCase):
def test_equal_dates_round_trip(self):
ev = Event(self.fixtureEqual)
self.assertEqual(ev.dateprior, 6515)
self.assertEqual(ev.dateafter, 6515)
self.assertEqual(ev.Rawrtctime, 1625159578)
self.assertEqual(ev.datePrior, 6515)
self.assertEqual(ev.dateAfter, 6515)
self.assertEqual(ev.rawRtcTime, 1625159578)
def test_off_by_one_dates_round_trip(self):
ev = Event(self.fixtureOffByOne)
self.assertEqual(ev.dateprior, 6530)
self.assertEqual(ev.dateafter, 6531)
self.assertEqual(ev.Rawrtctime, 2958809165)
self.assertEqual(ev.datePrior, 6530)
self.assertEqual(ev.dateAfter, 6531)
self.assertEqual(ev.rawRtcTime, 2958809165)
def test_large_jump_dates_round_trip(self):
ev = Event(self.fixtureLargeJump)
self.assertEqual(ev.dateprior, 4394)
self.assertEqual(ev.dateafter, 6410)
self.assertEqual(ev.Rawrtctime, 1089120495)
self.assertEqual(ev.datePrior, 4394)
self.assertEqual(ev.dateAfter, 6410)
self.assertEqual(ev.rawRtcTime, 1089120495)
def test_todict_is_json_serializable(self):
for fx in (self.fixtureEqual, self.fixtureOffByOne, self.fixtureLargeJump):
@@ -86,9 +86,9 @@ class TestLidDateChanged(unittest.TestCase):
self.assertEqual(d["id"], 14)
self.assertEqual(d["name"], "LID_DATE_CHANGED")
self.assertEqual(d["seqNum"], fx["sequenceNumber"])
self.assertEqual(d["dateprior"], fx["eventProperties"]["datePrior"])
self.assertEqual(d["dateafter"], fx["eventProperties"]["dateAfter"])
self.assertEqual(d["Rawrtctime"], fx["eventProperties"]["rawRtcTime"])
self.assertEqual(d["datePrior"], fx["eventProperties"]["datePrior"])
self.assertEqual(d["dateAfter"], fx["eventProperties"]["dateAfter"])
self.assertEqual(d["rawRtcTime"], fx["eventProperties"]["rawRtcTime"])
if __name__ == "__main__":
+10 -10
View File
@@ -80,26 +80,26 @@ class TestLidNewDay(unittest.TestCase):
def test_commanded_basal_rate_zero(self):
ev = Event(self.fixtureZeroBasal)
self.assertEqual(ev.commandedbasalrate, 0)
self.assertEqual(ev.commandedBasalRate, 0)
def test_commanded_basal_rate_fractional(self):
ev = Event(self.fixtureFractionalBasal)
self.assertEqual(ev.commandedbasalrate, 0.763)
self.assertEqual(ev.commandedBasalRate, 0.763)
def test_commanded_basal_rate_unit(self):
ev = Event(self.fixtureUnitBasal)
self.assertEqual(ev.commandedbasalrate, 1)
self.assertEqual(ev.commandedBasalRate, 1)
def test_features_bitmask_holds_list_verbatim(self):
# No transform on the schema: the captured list is stored as-is.
ev = Event(self.fixtureZeroBasal)
self.assertEqual(ev.featuresbitmask, [])
self.assertIsInstance(ev.featuresbitmask, list)
self.assertEqual(ev.featuresBitmask, [])
self.assertIsInstance(ev.featuresBitmask, list)
def test_feature_bitmask_index_holds_list_verbatim(self):
ev = Event(self.fixtureZeroBasal)
self.assertEqual(ev.featurebitmaskindex, [])
self.assertIsInstance(ev.featurebitmaskindex, list)
self.assertEqual(ev.featureBitmaskIndex, [])
self.assertIsInstance(ev.featureBitmaskIndex, list)
def test_todict_is_json_serializable(self):
ev = Event(self.fixtureFractionalBasal)
@@ -108,9 +108,9 @@ class TestLidNewDay(unittest.TestCase):
self.assertEqual(d["id"], 90)
self.assertEqual(d["name"], "LID_NEW_DAY")
self.assertEqual(d["seqNum"], 396368)
self.assertEqual(d["commandedbasalrate"], 0.763)
self.assertEqual(d["featuresbitmask"], [])
self.assertEqual(d["featurebitmaskindex"], [])
self.assertEqual(d["commandedBasalRate"], 0.763)
self.assertEqual(d["featuresBitmask"], [])
self.assertEqual(d["featureBitmaskIndex"], [])
if __name__ == "__main__":
@@ -50,14 +50,14 @@ class TestLidPumpingResumed(unittest.TestCase):
def test_plain_fields(self):
ev = Event(self.fixtureA)
self.assertEqual(ev.preresumestate, 100)
self.assertEqual(ev.insulinamount, 105)
self.assertEqual(ev.preResumeState, 100)
self.assertEqual(ev.insulinAmount, 105)
def test_insulin_amount_varies_across_captures(self):
self.assertEqual(Event(self.fixtureA).insulinamount, 105)
self.assertEqual(Event(self.fixtureB).insulinamount, 13)
self.assertEqual(Event(self.fixtureA).insulinAmount, 105)
self.assertEqual(Event(self.fixtureB).insulinAmount, 13)
# preResumeState is constant across real captures.
self.assertEqual(Event(self.fixtureB).preresumestate, 100)
self.assertEqual(Event(self.fixtureB).preResumeState, 100)
def test_todict_is_json_serializable(self):
ev = Event(self.fixtureB)
@@ -66,8 +66,8 @@ class TestLidPumpingResumed(unittest.TestCase):
self.assertEqual(d["id"], 12)
self.assertEqual(d["name"], "LID_PUMPING_RESUMED")
self.assertEqual(d["seqNum"], 478545)
self.assertEqual(d["preresumestate"], 100)
self.assertEqual(d["insulinamount"], 13)
self.assertEqual(d["preResumeState"], 100)
self.assertEqual(d["insulinAmount"], 13)
if __name__ == "__main__":
@@ -56,22 +56,22 @@ class TestLidPumpingSuspended(unittest.TestCase):
def test_plain_fields_round_trip(self):
ev = Event(self.fixtureA)
self.assertEqual(ev.presuspendstate, 106)
self.assertEqual(ev.insulinamount, 120)
self.assertEqual(ev.rpatimeout, 15)
self.assertEqual(ev.preSuspendState, 106)
self.assertEqual(ev.insulinAmount, 120)
self.assertEqual(ev.rpaTimeout, 15)
def test_suspendreason_resolves_to_enum(self):
# suspendReason:0 -> UserAborted
ev = Event(self.fixtureA)
self.assertEqual(ev.suspendreasonRaw, 0)
self.assertEqual(ev.suspendreason,
self.assertEqual(ev.suspendReasonRaw, 0)
self.assertEqual(ev.suspendReason,
eventtypes.LidPumpingSuspended.SuspendreasonEnum.UserAborted)
def test_second_capture_distinct_insulin_amount(self):
ev = Event(self.fixtureB)
self.assertEqual(ev.seqNum, 401271)
self.assertEqual(ev.insulinamount, 150)
self.assertEqual(ev.suspendreason,
self.assertEqual(ev.insulinAmount, 150)
self.assertEqual(ev.suspendReason,
eventtypes.LidPumpingSuspended.SuspendreasonEnum.UserAborted)
def test_todict_is_json_serializable(self):
@@ -80,8 +80,8 @@ class TestLidPumpingSuspended(unittest.TestCase):
json.dumps(d) # must not raise
self.assertEqual(d["id"], 11)
self.assertEqual(d["name"], "LID_PUMPING_SUSPENDED")
self.assertEqual(d["insulinamount"], 120)
self.assertEqual(d["suspendreasonRaw"], 0)
self.assertEqual(d["insulinAmount"], 120)
self.assertEqual(d["suspendReasonRaw"], 0)
if __name__ == "__main__":
+11 -11
View File
@@ -67,22 +67,22 @@ class TestLidTimeChanged(unittest.TestCase):
def test_time_fields_round_trip(self):
ev = Event(self.fixtureForward)
self.assertEqual(ev.timeprior, 12513657)
self.assertEqual(ev.timeafter, 37691000)
self.assertEqual(ev.Rawrtctime, 1380540797)
self.assertEqual(ev.timePrior, 12513657)
self.assertEqual(ev.timeAfter, 37691000)
self.assertEqual(ev.rawRtcTime, 1380540797)
ev = Event(self.fixtureBackward)
self.assertEqual(ev.timeprior, 59278139)
self.assertEqual(ev.timeafter, 55657000)
self.assertEqual(ev.Rawrtctime, 1625159580)
self.assertEqual(ev.timePrior, 59278139)
self.assertEqual(ev.timeAfter, 55657000)
self.assertEqual(ev.rawRtcTime, 1625159580)
def test_forward_and_backward_direction(self):
# timeAfter > timePrior means the clock jumped forward, and vice versa.
fwd = Event(self.fixtureForward)
self.assertGreater(fwd.timeafter, fwd.timeprior)
self.assertGreater(fwd.timeAfter, fwd.timePrior)
bwd = Event(self.fixtureBackward)
self.assertLess(bwd.timeafter, bwd.timeprior)
self.assertLess(bwd.timeAfter, bwd.timePrior)
def test_todict_is_json_serializable(self):
for fixture in (self.fixtureForward, self.fixtureBackward):
@@ -91,9 +91,9 @@ class TestLidTimeChanged(unittest.TestCase):
json.dumps(d) # must not raise
self.assertEqual(d["id"], 13)
self.assertEqual(d["name"], "LID_TIME_CHANGED")
self.assertEqual(d["timeprior"], fixture["eventProperties"]["timePrior"])
self.assertEqual(d["timeafter"], fixture["eventProperties"]["timeAfter"])
self.assertEqual(d["Rawrtctime"], fixture["eventProperties"]["rawRtcTime"])
self.assertEqual(d["timePrior"], fixture["eventProperties"]["timePrior"])
self.assertEqual(d["timeAfter"], fixture["eventProperties"]["timeAfter"])
self.assertEqual(d["rawRtcTime"], fixture["eventProperties"]["rawRtcTime"])
if __name__ == "__main__":
@@ -58,7 +58,7 @@ class TestLidTubingFilled(unittest.TestCase):
def test_negative_primesize_sentinel_round_trips(self):
# -1 is a sentinel and must survive verbatim (not treated as missing).
ev = Event(self.fixtureNegativePrimeSize)
self.assertEqual(ev.primesize, -1)
self.assertEqual(ev.primeSize, -1)
def test_position_round_trips(self):
ev = Event(self.fixtureNegativePrimeSize)
@@ -66,16 +66,16 @@ class TestLidTubingFilled(unittest.TestCase):
def test_completionstatus_resolves_to_completed(self):
ev = Event(self.fixtureNegativePrimeSize)
self.assertEqual(ev.completionstatusRaw, 3)
self.assertEqual(ev.completionstatus,
self.assertEqual(ev.completionStatusRaw, 3)
self.assertEqual(ev.completionStatus,
eventtypes.LidTubingFilled.CompletionstatusEnum.Completed)
def test_second_capture_distinct_values(self):
ev = Event(self.fixtureCompleted)
self.assertEqual(ev.seqNum, 401423)
self.assertEqual(ev.position, 594056)
self.assertEqual(ev.primesize, -1)
self.assertEqual(ev.completionstatus,
self.assertEqual(ev.primeSize, -1)
self.assertEqual(ev.completionStatus,
eventtypes.LidTubingFilled.CompletionstatusEnum.Completed)
self.assertEqual(ev.eventTimestamp.format('YYYY-MM-DDTHH:mm:ss'),
"2026-05-02T12:27:17")
@@ -87,8 +87,8 @@ class TestLidTubingFilled(unittest.TestCase):
self.assertEqual(td["id"], 63)
self.assertEqual(td["name"], "LID_TUBING_FILLED")
self.assertEqual(td["seqNum"], 394428)
self.assertEqual(td["primesize"], -1)
self.assertEqual(td["completionstatusRaw"], 3)
self.assertEqual(td["primeSize"], -1)
self.assertEqual(td["completionStatusRaw"], 3)
self.assertEqual(td["position"], 631224)
@@ -47,10 +47,10 @@ class TestLidVersionsA(unittest.TestCase):
def test_plain_fields_round_trip(self):
ev = Event(self.fixtureVersions)
self.assertEqual(ev.armpartnumber, 1016587)
self.assertEqual(ev.armswversion, 1108201743)
self.assertEqual(ev.blepartnumber, 1016587)
self.assertEqual(ev.bleswversion, 1108201743)
self.assertEqual(ev.armPartNumber, 1016587)
self.assertEqual(ev.armSwVersion, 1108201743)
self.assertEqual(ev.blePartNumber, 1016587)
self.assertEqual(ev.bleSwVersion, 1108201743)
def test_todict_is_json_serializable(self):
ev = Event(self.fixtureVersions)
@@ -59,10 +59,10 @@ class TestLidVersionsA(unittest.TestCase):
self.assertEqual(d["id"], 307)
self.assertEqual(d["name"], "LID_VERSIONS_A")
self.assertEqual(d["seqNum"], 393111)
self.assertEqual(d["armpartnumber"], 1016587)
self.assertEqual(d["armswversion"], 1108201743)
self.assertEqual(d["blepartnumber"], 1016587)
self.assertEqual(d["bleswversion"], 1108201743)
self.assertEqual(d["armPartNumber"], 1016587)
self.assertEqual(d["armSwVersion"], 1108201743)
self.assertEqual(d["blePartNumber"], 1016587)
self.assertEqual(d["bleSwVersion"], 1108201743)
if __name__ == "__main__":
+12 -12
View File
@@ -136,16 +136,16 @@ class TestEnumAndRatioFields(unittest.TestCase):
def test_dictionary_enum_resolves_from_raw_int(self):
# alarmId:18 -> ResumePumpAlarm (stored on the alarmidRaw attr)
ev = Event(ALARM_5)
self.assertEqual(ev.alarmidRaw, 18)
self.assertEqual(ev.alarmid,
self.assertEqual(ev.alarmIdRaw, 18)
self.assertEqual(ev.alarmId,
eventtypes.LidAlarmActivated.AlarmidEnum.ResumePumpAlarm)
def test_multiple_enums_on_one_event(self):
# requestedAction:2 -> StopSleep; previousUserMode:1 -> Sleeping
ev = Event(UMC_229)
self.assertEqual(ev.requestedaction,
self.assertEqual(ev.requestedAction,
eventtypes.LidAaUserModeChange.RequestedactionEnum.StopSleep)
self.assertEqual(ev.previoususermode,
self.assertEqual(ev.previousUserMode,
eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Sleeping)
def test_ratio_field_scales(self):
@@ -157,8 +157,8 @@ class TestEnumAndRatioFields(unittest.TestCase):
def test_enum_zero_value_resolves(self):
# glucoseValueStatus:0 -> PreciseValue (0 must not be treated as missing)
ev = Event(CGM_399)
self.assertEqual(ev.glucosevaluestatusRaw, 0)
self.assertEqual(ev.glucosevaluestatus,
self.assertEqual(ev.glucoseValueStatusRaw, 0)
self.assertEqual(ev.glucoseValueStatus,
eventtypes.LidCgmDataG7.GlucosevaluestatusEnum.PreciseValue)
@@ -170,8 +170,8 @@ class TestBitmaskFields(unittest.TestCase):
def test_single_bit_array(self):
# activeSleepSchedule:[0] -> 1<<0 == 1
ev = Event(UMC_229)
self.assertEqual(ev.activesleepscheduleRaw, 1)
self.assertEqual(ev.activesleepschedule,
self.assertEqual(ev.activeSleepScheduleRaw, 1)
self.assertEqual(ev.activeSleepSchedule,
eventtypes.LidAaUserModeChange.ActivesleepscheduleBitmask.SleepSchedule1IsActive)
def test_cgm_datatype_array(self):
@@ -193,12 +193,12 @@ class TestBitmaskFields(unittest.TestCase):
event = dict(UMC_229)
event["eventProperties"] = dict(UMC_229["eventProperties"], activeSleepSchedule=[])
ev = Event(event)
self.assertEqual(ev.activesleepscheduleRaw, 0)
self.assertEqual(ev.activeSleepScheduleRaw, 0)
class TestRawFieldShims(unittest.TestCase):
"""#15: process_device_status sorts on event.raw.timestamp; ProcessCGMReading
reads event.egvTimestamp as raw seconds both must survive the JSON path."""
reads event.egvTimeStamp as raw seconds both must survive the JSON path."""
maxDiff = None
def test_raw_timestamp_shim_available(self):
@@ -212,8 +212,8 @@ class TestRawFieldShims(unittest.TestCase):
# egvTimeStamp (camelCase in the JSON) normalizes onto egvTimestamp and is
# kept as a raw seconds int; ProcessCGMReading adds TANDEM_EPOCH to it.
ev = Event(CGM_399)
self.assertEqual(ev.egvTimestamp, 579571288)
self.assertEqual(ev.currentglucosedisplayvalue, 167)
self.assertEqual(ev.egvTimeStamp, 579571288)
self.assertEqual(ev.currentGlucoseDisplayValue, 167)
if __name__ == "__main__":
@@ -28,7 +28,7 @@ class TestProcessAlarm(unittest.TestCase):
]
self.assertEqual(type(events[0]), eventtypes.LidAlarmActivated)
self.assertEqual(events[0].alarmid, eventtypes.LidAlarmActivated.AlarmidEnum.ResumePumpAlarm)
self.assertEqual(events[0].alarmId, eventtypes.LidAlarmActivated.AlarmidEnum.ResumePumpAlarm)
p = self.process.process(events, time_start=None, time_end=None)
@@ -44,7 +44,7 @@ class TestProcessAlarm(unittest.TestCase):
]
self.assertEqual(type(events[0]), eventtypes.LidAlarmActivated)
self.assertEqual(events[0].alarmid, eventtypes.LidAlarmActivated.AlarmidEnum.EmptyCartridgeAlarm)
self.assertEqual(events[0].alarmId, eventtypes.LidAlarmActivated.AlarmidEnum.EmptyCartridgeAlarm)
p = self.process.process(events, time_start=None, time_end=None)
@@ -39,9 +39,9 @@ class TestProcessCGMReadingG7(unittest.TestCase):
self.assertEqual(type(events[0]), eventtypes.LidCgmDataG7)
self.assertEqual(events[0].raw.timestampRaw, 566504207)
self.assertEqual(events[0].egvTimestamp, 566504204)
self.assertEqual(events[0].egvTimeStamp, 566504204)
self.assertEqual(events[0].seqNum, 505869)
self.assertEqual(events[0].currentglucosedisplayvalue, 80)
self.assertEqual(events[0].currentGlucoseDisplayValue, 80)
self.assertEqual(events[0].rateRaw, -9)
p = self.process.process(events, time_start=None, time_end=None)
@@ -63,9 +63,9 @@ class TestProcessCGMReadingG7(unittest.TestCase):
for event in events:
self.assertEqual(type(event), eventtypes.LidCgmDataG7)
self.assertEqual(events[0].currentglucosedisplayvalue, 80)
self.assertEqual(events[1].currentglucosedisplayvalue, 71)
self.assertEqual(events[2].currentglucosedisplayvalue, 119)
self.assertEqual(events[0].currentGlucoseDisplayValue, 80)
self.assertEqual(events[1].currentGlucoseDisplayValue, 71)
self.assertEqual(events[2].currentGlucoseDisplayValue, 119)
p = self.process.process(events, time_start=None, time_end=None)
@@ -139,8 +139,8 @@ class TestProcessCGMReadingG6(unittest.TestCase):
# timestamp 2022-01-28T00:01:09 confirmed w/ tandem csv export
self.assertEqual(type(events[0]), eventtypes.LidCgmDataGxb)
self.assertEqual(events[0].raw.timestampRaw, 444182469)
self.assertEqual(events[0].egvTimestamp, 444182469)
self.assertEqual(events[0].currentglucosedisplayvalue, 75)
self.assertEqual(events[0].egvTimeStamp, 444182469)
self.assertEqual(events[0].currentGlucoseDisplayValue, 75)
self.assertEqual(events[0].rateRaw, -4)
p = self.process.process(events, time_start=None, time_end=None)
@@ -162,9 +162,9 @@ class TestProcessCGMReadingG6(unittest.TestCase):
for event in events:
self.assertEqual(type(event), eventtypes.LidCgmDataGxb)
self.assertEqual(events[0].currentglucosedisplayvalue, 75)
self.assertEqual(events[1].currentglucosedisplayvalue, 77)
self.assertEqual(events[2].currentglucosedisplayvalue, 76)
self.assertEqual(events[0].currentGlucoseDisplayValue, 75)
self.assertEqual(events[1].currentGlucoseDisplayValue, 77)
self.assertEqual(events[2].currentGlucoseDisplayValue, 76)
p = self.process.process(events, time_start=None, time_end=None)
@@ -191,11 +191,11 @@ class TestProcessCGMReadingG6(unittest.TestCase):
for event in events:
self.assertEqual(type(event), eventtypes.LidCgmDataGxb)
self.assertEqual(events[0].currentglucosedisplayvalue, 75)
self.assertEqual(events[1].currentglucosedisplayvalue, 77)
self.assertEqual(events[2].currentglucosedisplayvalue, 76) # backfill
self.assertEqual(events[3].currentglucosedisplayvalue, 75)
self.assertEqual(events[4].currentglucosedisplayvalue, 74)
self.assertEqual(events[0].currentGlucoseDisplayValue, 75)
self.assertEqual(events[1].currentGlucoseDisplayValue, 77)
self.assertEqual(events[2].currentGlucoseDisplayValue, 76) # backfill
self.assertEqual(events[3].currentGlucoseDisplayValue, 75)
self.assertEqual(events[4].currentGlucoseDisplayValue, 74)
self.assertEqual(events[0].raw.timestampRaw, 444182469)
self.assertEqual(events[1].raw.timestampRaw, 444182768)
@@ -203,11 +203,11 @@ class TestProcessCGMReadingG6(unittest.TestCase):
self.assertEqual(events[3].raw.timestampRaw, 444189367)
self.assertEqual(events[4].raw.timestampRaw, 444189666)
self.assertEqual(events[0].egvTimestamp, 444182469)
self.assertEqual(events[1].egvTimestamp, 444182768)
self.assertEqual(events[2].egvTimestamp, 444189067)
self.assertEqual(events[3].egvTimestamp, 444189367)
self.assertEqual(events[4].egvTimestamp, 444189666)
self.assertEqual(events[0].egvTimeStamp, 444182469)
self.assertEqual(events[1].egvTimeStamp, 444182768)
self.assertEqual(events[2].egvTimeStamp, 444189067)
self.assertEqual(events[3].egvTimeStamp, 444189367)
self.assertEqual(events[4].egvTimeStamp, 444189666)
p = self.process.process(events, time_start=None, time_end=None)
@@ -381,7 +381,7 @@ class TestProcessCGMReadingFSL3(unittest.TestCase):
self.assertEqual(type(events[0]), eventtypes.LidCgmDataFsl3)
self.assertEqual(events[0].seqNum, 785470)
self.assertEqual(events[0].currentglucosedisplayvalue, 149)
self.assertEqual(events[0].currentGlucoseDisplayValue, 149)
p = self.process.process(events, time_start=None, time_end=None)
@@ -400,8 +400,8 @@ class TestProcessCGMReadingFSL3(unittest.TestCase):
for event in events:
self.assertEqual(type(event), eventtypes.LidCgmDataFsl3)
self.assertEqual(events[0].currentglucosedisplayvalue, 149)
self.assertEqual(events[1].currentglucosedisplayvalue, 149)
self.assertEqual(events[0].currentGlucoseDisplayValue, 149)
self.assertEqual(events[1].currentGlucoseDisplayValue, 149)
p = self.process.process(events, time_start=None, time_end=None)
@@ -443,7 +443,7 @@ class TestProcessCGMReadingG7Json(unittest.TestCase):
def test_single_g7_json_reading(self):
events = list(Events([dict(G7_JSON_1)]))
self.assertEqual(type(events[0]), eventtypes.LidCgmDataG7)
self.assertEqual(events[0].egvTimestamp, 578966461)
self.assertEqual(events[0].egvTimeStamp, 578966461)
p = self.process.process(events, time_start=None, time_end=None)
self.assertEqual(len(p), 1)
@@ -516,7 +516,7 @@ class TestProcessCGMReadingG6Json(unittest.TestCase):
def test_single_g6_json_reading(self):
events = list(Events([dict(G6_JSON_1)]))
self.assertEqual(type(events[0]), eventtypes.LidCgmDataGxb)
self.assertEqual(events[0].egvTimestamp, 474023314)
self.assertEqual(events[0].egvTimeStamp, 474023314)
p = self.process.process(events, time_start=None, time_end=None)
self.assertEqual(len(p), 1)
@@ -29,9 +29,9 @@ class TestProcessDeviceStatus(unittest.TestCase):
]
self.assertEqual(type(events[0]), eventtypes.LidDailyBasal)
self.assertEqual(events[0].batterychargepercentmsbRaw, 14)
self.assertEqual(events[0].batterychargepercentlsbRaw, 246)
self.assertEqual(events[0].batterylipomillivolts, 14080)
self.assertEqual(events[0].batteryChargePercentMSBRaw, 14)
self.assertEqual(events[0].batteryChargePercentLSBRaw, 246)
self.assertEqual(events[0].batteryLipoMilliVolts, 14080)
p = self.process.process(events, time_start=None, time_end=None)
@@ -58,9 +58,9 @@ class TestProcessDeviceStatus(unittest.TestCase):
]
self.assertEqual(type(events[0]), eventtypes.LidDailyBasal)
self.assertEqual(events[0].batterychargepercentmsbRaw, 14)
self.assertEqual(events[0].batterychargepercentlsbRaw, 246)
self.assertEqual(events[0].batterylipomillivolts, 14080)
self.assertEqual(events[0].batteryChargePercentMSBRaw, 14)
self.assertEqual(events[0].batteryChargePercentLSBRaw, 246)
self.assertEqual(events[0].batteryLipoMilliVolts, 14080)
p = self.process.process(events, time_start=None, time_end=None)
@@ -77,15 +77,15 @@ class TestProcessDeviceStatus(unittest.TestCase):
self.assertEqual(type(events[0]), eventtypes.LidDailyBasal)
self.assertEqual(events[0].raw.timestampRaw, 534123623) # 2024-12-03 23:40:23-05:00
self.assertEqual(events[0].batterychargepercentmsbRaw, 14)
self.assertEqual(events[0].batterychargepercentlsbRaw, 246)
self.assertEqual(events[0].batterylipomillivolts, 14080)
self.assertEqual(events[0].batteryChargePercentMSBRaw, 14)
self.assertEqual(events[0].batteryChargePercentLSBRaw, 246)
self.assertEqual(events[0].batteryLipoMilliVolts, 14080)
self.assertEqual(type(events[1]), eventtypes.LidDailyBasal)
self.assertEqual(events[1].raw.timestampRaw, 534133823) # 2024-12-04 02:30:23-05:00
self.assertEqual(events[1].batterychargepercentmsbRaw, 14)
self.assertEqual(events[1].batterychargepercentlsbRaw, 243)
self.assertEqual(events[1].batterylipomillivolts, 13824)
self.assertEqual(events[1].batteryChargePercentMSBRaw, 14)
self.assertEqual(events[1].batteryChargePercentLSBRaw, 243)
self.assertEqual(events[1].batteryLipoMilliVolts, 13824)
p = self.process.process(events, time_start=None, time_end=None)
@@ -115,21 +115,21 @@ class TestProcessDeviceStatus(unittest.TestCase):
self.assertEqual(type(events[0]), eventtypes.LidDailyBasal)
self.assertEqual(events[0].raw.timestampRaw, 534123623) # 2024-12-03 23:40:23-05:00
self.assertEqual(events[0].batterychargepercentmsbRaw, 14)
self.assertEqual(events[0].batterychargepercentlsbRaw, 246)
self.assertEqual(events[0].batterylipomillivolts, 14080)
self.assertEqual(events[0].batteryChargePercentMSBRaw, 14)
self.assertEqual(events[0].batteryChargePercentLSBRaw, 246)
self.assertEqual(events[0].batteryLipoMilliVolts, 14080)
self.assertEqual(type(events[1]), eventtypes.LidDailyBasal)
self.assertEqual(events[1].raw.timestampRaw, 534133823) # 2024-12-04 02:30:23-05:00
self.assertEqual(events[1].batterychargepercentmsbRaw, 14)
self.assertEqual(events[1].batterychargepercentlsbRaw, 243)
self.assertEqual(events[1].batterylipomillivolts, 13824)
self.assertEqual(events[1].batteryChargePercentMSBRaw, 14)
self.assertEqual(events[1].batteryChargePercentLSBRaw, 243)
self.assertEqual(events[1].batteryLipoMilliVolts, 13824)
self.assertEqual(type(events[2]), eventtypes.LidDailyBasal)
self.assertEqual(events[2].raw.timestampRaw, 534145823) # 2024-12-04 05:50:23-05:00
self.assertEqual(events[2].batterychargepercentmsbRaw, 14)
self.assertEqual(events[2].batterychargepercentlsbRaw, 238)
self.assertEqual(events[2].batterylipomillivolts, 13568)
self.assertEqual(events[2].batteryChargePercentMSBRaw, 14)
self.assertEqual(events[2].batteryChargePercentLSBRaw, 238)
self.assertEqual(events[2].batteryLipoMilliVolts, 13568)
p = self.process.process(events, time_start=None, time_end=None)
@@ -178,12 +178,12 @@ class TestProcessDeviceStatus(unittest.TestCase):
})
event = eventtypes.LidDailyBasal(
raw=raw,
dailytotalbasal=None,
lastbasalrate=None,
dailyTotalBasal=None,
lastBasalRate=None,
iob=None,
batterychargepercentmsbRaw=None,
batterychargepercentlsbRaw=None,
batterylipomillivolts=None,
batteryChargePercentMSBRaw=None,
batteryChargePercentLSBRaw=None,
batteryLipoMilliVolts=None,
)
p = self.process.process([event], time_start=None, time_end=None)
@@ -198,8 +198,8 @@ class TestProcessDeviceStatus(unittest.TestCase):
# p = self.process.process([event], time_start=None, time_end=None)
# self.assertEqual(len(p), 1)
# self.assertEqual(p[0]['pump']['battery']['status'], percent_str)
msb = event.batterychargepercentmsbRaw
lsb = event.batterychargepercentlsbRaw
msb = event.batteryChargePercentMSBRaw
lsb = event.batteryChargePercentLSBRaw
MAX = struct.unpack(UINT16, bytearray((16, 128)))[0]
@@ -231,51 +231,51 @@ class TestProcessDeviceStatus(unittest.TestCase):
# Mobi @ MAX seen
# bytearray(b'\x00Q \x19U=\x00\x01\x0f\xa8A\xa5\x04V?L\xcc\xcd?s\x83b\x10Pd\x01')
# batterychargepercentmsbRaw=16, batterychargepercentlsbRaw=80, batterylipomillivolts=25601
# batteryChargePercentMSBRaw=16, batteryChargePercentLSBRaw=80, batteryLipoMilliVolts=25601
# Mobi @ ~80%
# bytearray(b'\x00Q\x1f\xfdm\xf5\x00\x00\x04P@4\xa7\xed?L\xcc\xcd@+\xd8\x81\x0f\xa1P\x00'):
# batterychargepercentmsbRaw=15, batterychargepercentlsbRaw=161, batterylipomillivolts=20480
# batteryChargePercentMSBRaw=15, batteryChargePercentLSBRaw=161, batteryLipoMilliVolts=20480
# calc batteryChargePercent = 0.54296875
# Mobi @ ~55%
# bytearray(b'\x00Q \x04\x15\xdd\x00\x00E\xb1A\x86\xe0\xcf\x00\x00\x00\x00A9\xd2w\x0f\x1d=\x00')
# batterychargepercentmsbRaw=15, batterychargepercentlsbRaw=29, batterylipomillivolts=15616
# batteryChargePercentMSBRaw=15, batteryChargePercentLSBRaw=29, batteryLipoMilliVolts=15616
# calc batteryChargePercent = 0.37109375
# Mobi @ ~45%
# bytearray(b'\x00Q \x04\xd8f\x00\x00L^A^\xc5\x9a>49X\x00\x00\x00\x00\x0e\xfa7\x00')
# batterychargepercentmsbRaw=14, batterychargepercentlsbRaw=250 batterylipomillivolts=14080
# batteryChargePercentMSBRaw=14, batteryChargePercentLSBRaw=250 batteryLipoMilliVolts=14080
# calc batteryChargePercent = 0.3255208333333333
# Mobi @ ~15%
# bytearray(b'\x00Q \x06#U\x00\x00X{A\t\xed\xeb?\tx\xd5<\xe0\x81[\x0e\xb5 \x00')
# batterychargepercentmsbRaw=14, batterychargepercentlsbRaw=181 batterylipomillivolts=8192
# batteryChargePercentMSBRaw=14, batteryChargePercentLSBRaw=181 batteryLipoMilliVolts=8192
# calc batteryChargePercent = 0.23567708333333334
# Mobi @ ~20%
# bytearray(b'\x00Q \x1d\xbb\xa5\x00\x019zA\x1e\x1f`@%p\xa4>\xad\xaa\xf1\x0e\xc1$\x00')
# batterychargepercentmsbRaw=14, batterychargepercentlsbRaw=193 batterylipomillivolts=9216
# batteryChargePercentMSBRaw=14, batteryChargePercentLSBRaw=193 batteryLipoMilliVolts=9216
# calc batteryChargePercent = 0.2513020833333333
# Mobi @ ~10%
# bytearray(b'\x00Q \x1e\\m\x00\x01?}A\xa0\xe2\x8b?L\xcc\xcd?\xda\xeaj\x0e\xa1\x1b\x00')
# batterychargepercentmsbRaw=14, batterychargepercentlsbRaw=161 batterylipomillivolts=6912
# batteryChargePercentMSBRaw=14, batteryChargePercentLSBRaw=161 batteryLipoMilliVolts=6912
# calc batteryChargePercent = 0.20963541666666666
# Mobi @ ~10%
# bytearray(b'\x00Q \x1ej~\x00\x01@2A\xa5\xafZ\x00\x00\x00\x00@\x8c[\xed\x0e\x9f\x1a\x00')
# batterychargepercentmsbRaw=14, batterychargepercentlsbRaw=159 batterylipomillivolts=6656
# batteryChargePercentMSBRaw=14, batteryChargePercentLSBRaw=159 batteryLipoMilliVolts=6656
# calc batteryChargePercent = 0.20703125
# Mobi @ ~5%
# bytearray(b'\x00Q \x1e\xa2\xbd\x00\x01C\x1a?\xd9?}@MO\xdf@uz<\x0e\x88\x15\x00')
# batterychargepercentmsbRaw=14, batterychargepercentlsbRaw=136
# calc batteryChargePercent = 0.17708333333333334 batterylipomillivolts=5376
# batteryChargePercentMSBRaw=14, batteryChargePercentLSBRaw=136
# calc batteryChargePercent = 0.17708333333333334 batteryLipoMilliVolts=5376
# Mobi @ ~5%
# bytearray(b'\x00Q \x1e\xb0\xcd\x00\x01C\xd3@L9W@#33@\x8b\x04\xd2\x0e\x88\x15\x00')
# batterychargepercentmsbRaw=14 batterychargepercentlsbRaw=136 batterylipomillivolts=5376
# batteryChargePercentMSBRaw=14 batteryChargePercentLSBRaw=136 batteryLipoMilliVolts=5376
# calc 0.17708333333333334
@@ -28,9 +28,9 @@ class TestProcessUserModeSleep(unittest.TestCase):
]
self.assertEqual(type(events[0]), eventtypes.LidAaUserModeChange)
self.assertEqual(events[0].previoususermode, eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Normal)
self.assertEqual(events[0].currentusermode, eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Sleeping)
self.assertEqual(events[0].requestedaction, eventtypes.LidAaUserModeChange.RequestedactionEnum.StartSleep)
self.assertEqual(events[0].previousUserMode, eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Normal)
self.assertEqual(events[0].currentUserMode, eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Sleeping)
self.assertEqual(events[0].requestedAction, eventtypes.LidAaUserModeChange.RequestedactionEnum.StartSleep)
time_end = arrow.get('2024-12-04T23:00:30-05:00')
p = self.process.process(events, time_start=None, time_end=time_end)
@@ -56,9 +56,9 @@ class TestProcessUserModeSleep(unittest.TestCase):
]
self.assertEqual(type(events[0]), eventtypes.LidAaUserModeChange)
self.assertEqual(events[0].previoususermode, eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Sleeping)
self.assertEqual(events[0].currentusermode, eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Normal)
self.assertEqual(events[0].requestedaction, eventtypes.LidAaUserModeChange.RequestedactionEnum.StopSleep)
self.assertEqual(events[0].previousUserMode, eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Sleeping)
self.assertEqual(events[0].currentUserMode, eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Normal)
self.assertEqual(events[0].requestedAction, eventtypes.LidAaUserModeChange.RequestedactionEnum.StopSleep)
time_end = arrow.get('2024-12-04T23:00:30-05:00')
p = self.process.process(events, time_start=None, time_end=time_end)
@@ -78,15 +78,15 @@ class TestProcessUserModeSleep(unittest.TestCase):
]
self.assertEqual(type(events[0]), eventtypes.LidAaUserModeChange)
self.assertEqual(events[0].previoususermode, eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Normal)
self.assertEqual(events[0].currentusermode, eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Sleeping)
self.assertEqual(events[0].requestedaction, eventtypes.LidAaUserModeChange.RequestedactionEnum.StartSleep)
self.assertEqual(events[0].previousUserMode, eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Normal)
self.assertEqual(events[0].currentUserMode, eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Sleeping)
self.assertEqual(events[0].requestedAction, eventtypes.LidAaUserModeChange.RequestedactionEnum.StartSleep)
self.assertEqual(type(events[1]), eventtypes.LidAaUserModeChange)
self.assertEqual(events[1].previoususermode, eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Sleeping)
self.assertEqual(events[1].currentusermode, eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Normal)
self.assertEqual(events[1].requestedaction, eventtypes.LidAaUserModeChange.RequestedactionEnum.StopSleep)
self.assertEqual(events[1].previousUserMode, eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Sleeping)
self.assertEqual(events[1].currentUserMode, eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Normal)
self.assertEqual(events[1].requestedAction, eventtypes.LidAaUserModeChange.RequestedactionEnum.StopSleep)
time_end = arrow.get('2024-12-05T10:00:00-05:00')
p = self.process.process(events, time_start=None, time_end=time_end)
@@ -123,9 +123,9 @@ class TestProcessUserModeSleep(unittest.TestCase):
]
self.assertEqual(type(events[0]), eventtypes.LidAaUserModeChange)
self.assertEqual(events[0].previoususermode, eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Sleeping)
self.assertEqual(events[0].currentusermode, eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Normal)
self.assertEqual(events[0].requestedaction, eventtypes.LidAaUserModeChange.RequestedactionEnum.StopSleep)
self.assertEqual(events[0].previousUserMode, eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Sleeping)
self.assertEqual(events[0].currentUserMode, eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Normal)
self.assertEqual(events[0].requestedAction, eventtypes.LidAaUserModeChange.RequestedactionEnum.StopSleep)
time_end = arrow.get('2024-12-05T10:00:00-05:00')
p = self.process.process(events, time_start=None, time_end=time_end)
@@ -161,9 +161,9 @@ class TestProcessUserModeExercise(unittest.TestCase):
]
self.assertEqual(type(events[0]), eventtypes.LidAaUserModeChange)
self.assertEqual(events[0].previoususermode, eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Normal)
self.assertEqual(events[0].currentusermode, eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Exercising)
self.assertEqual(events[0].requestedaction, eventtypes.LidAaUserModeChange.RequestedactionEnum.StartExercise)
self.assertEqual(events[0].previousUserMode, eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Normal)
self.assertEqual(events[0].currentUserMode, eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Exercising)
self.assertEqual(events[0].requestedAction, eventtypes.LidAaUserModeChange.RequestedactionEnum.StartExercise)
time_end = arrow.get('2024-12-04T23:00:30-05:00')
p = self.process.process(events, time_start=None, time_end=time_end)
@@ -189,9 +189,9 @@ class TestProcessUserModeExercise(unittest.TestCase):
]
self.assertEqual(type(events[0]), eventtypes.LidAaUserModeChange)
self.assertEqual(events[0].previoususermode, eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Exercising)
self.assertEqual(events[0].currentusermode, eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Normal)
self.assertEqual(events[0].requestedaction, eventtypes.LidAaUserModeChange.RequestedactionEnum.StopExercise)
self.assertEqual(events[0].previousUserMode, eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Exercising)
self.assertEqual(events[0].currentUserMode, eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Normal)
self.assertEqual(events[0].requestedAction, eventtypes.LidAaUserModeChange.RequestedactionEnum.StopExercise)
time_end = arrow.get('2024-12-04T23:00:30-05:00')
p = self.process.process(events, time_start=None, time_end=time_end)
@@ -211,15 +211,15 @@ class TestProcessUserModeExercise(unittest.TestCase):
]
self.assertEqual(type(events[0]), eventtypes.LidAaUserModeChange)
self.assertEqual(events[0].previoususermode, eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Normal)
self.assertEqual(events[0].currentusermode, eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Exercising)
self.assertEqual(events[0].requestedaction, eventtypes.LidAaUserModeChange.RequestedactionEnum.StartExercise)
self.assertEqual(events[0].previousUserMode, eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Normal)
self.assertEqual(events[0].currentUserMode, eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Exercising)
self.assertEqual(events[0].requestedAction, eventtypes.LidAaUserModeChange.RequestedactionEnum.StartExercise)
self.assertEqual(type(events[1]), eventtypes.LidAaUserModeChange)
self.assertEqual(events[1].previoususermode, eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Exercising)
self.assertEqual(events[1].currentusermode, eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Normal)
self.assertEqual(events[1].requestedaction, eventtypes.LidAaUserModeChange.RequestedactionEnum.StopExercise)
self.assertEqual(events[1].previousUserMode, eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Exercising)
self.assertEqual(events[1].currentUserMode, eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Normal)
self.assertEqual(events[1].requestedAction, eventtypes.LidAaUserModeChange.RequestedactionEnum.StopExercise)
time_end = arrow.get('2024-12-05T10:00:00-05:00')
p = self.process.process(events, time_start=None, time_end=time_end)
@@ -256,9 +256,9 @@ class TestProcessUserModeExercise(unittest.TestCase):
]
self.assertEqual(type(events[0]), eventtypes.LidAaUserModeChange)
self.assertEqual(events[0].previoususermode, eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Exercising)
self.assertEqual(events[0].currentusermode, eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Normal)
self.assertEqual(events[0].requestedaction, eventtypes.LidAaUserModeChange.RequestedactionEnum.StopExercise)
self.assertEqual(events[0].previousUserMode, eventtypes.LidAaUserModeChange.PrevioususermodeEnum.Exercising)
self.assertEqual(events[0].currentUserMode, eventtypes.LidAaUserModeChange.CurrentusermodeEnum.Normal)
self.assertEqual(events[0].requestedAction, eventtypes.LidAaUserModeChange.RequestedactionEnum.StopExercise)
time_end = arrow.get('2024-12-05T10:00:00-05:00')
p = self.process.process(events, time_start=None, time_end=time_end)