diff --git a/xdrip/BluetoothTransmitter/CGM/Dexcom/G7/CGMG7Transmitter.swift b/xdrip/BluetoothTransmitter/CGM/Dexcom/G7/CGMG7Transmitter.swift index c0c1c9e04..b67f5a98a 100644 --- a/xdrip/BluetoothTransmitter/CGM/Dexcom/G7/CGMG7Transmitter.swift +++ b/xdrip/BluetoothTransmitter/CGM/Dexcom/G7/CGMG7Transmitter.swift @@ -210,25 +210,29 @@ class CGMG7Transmitter: BluetoothTransmitter, CGMTransmitter { return } - var maxSensorAgeInDays = ConstantsDexcomG7.maxSensorAgeInDays - - // check if it's a Stelo and if so, update the maxSensorAge - if let transmitterIdString = UserDefaults.standard.activeSensorTransmitterId, transmitterIdString.startsWith("DX01") { - maxSensorAgeInDays = ConstantsDexcomG7.maxSensorAgeInDaysStelo - } - let sensorAgeInDays = Double(round((g7GlucoseMessage.sensorAge / 3600 / 24) * 10) / 10) - // G7/ONE+/Stelo has the peculiarity that it will keep sending/repeating the same BG value (without ever changing) via BLE even after the session officially ends. - // to avoid this, let's check if the sensor is still within maxSensorAge before we continue - guard sensorAgeInDays < maxSensorAgeInDays else { - trace(" G7 is expired so will not process reading. sensorAge: %{public}@ / maxSensorAgeInDays: %{public}@", log: log, category: ConstantsLog.categoryCGMG7, type: .error, sensorAgeInDays.description, maxSensorAgeInDays.description) - return + var maxSensorAgeInDays: Double = 0.0 + + // check if we already have the transmitterId (or device name). If so, set the maxSensorAge and then perform a quick check to see if the sensor hasn't expired. + if let transmitterIdString = UserDefaults.standard.activeSensorTransmitterId { + if transmitterIdString.startsWith("DX01") { + maxSensorAgeInDays = ConstantsDexcomG7.maxSensorAgeInDaysStelo + } else { + maxSensorAgeInDays = ConstantsDexcomG7.maxSensorAgeInDays + } + + // G7/ONE+/Stelo has the peculiarity that it will keep sending/repeating the same BG value (without ever changing) via BLE even after the session officially ends. + // to avoid this, let's check if the sensor is still within maxSensorAge before we continue + if sensorAgeInDays > maxSensorAgeInDays { + trace(" %{public}@ is expired so will not process reading. sensorAge: %{public}@ / maxSensorAgeInDays: %{public}@", log: log, category: ConstantsLog.categoryCGMG7, type: .error, UserDefaults.standard.activeSensorTransmitterId ?? "sensor", sensorAgeInDays.description, maxSensorAgeInDays.description) + return + } } trace(" received g7GlucoseMessage mesage, calculatedValue = %{public}@, timeStamp = %{public}@, sensorAge = %{public}@ / %{public}@", log: log, category: ConstantsLog.categoryCGMG7, type: .info, g7GlucoseMessage.calculatedValue.description, g7GlucoseMessage.timeStamp.description(with: .current)) - trace(" received g7GlucoseMessage mesage, sensorAge = %{public}@ / %{public}@", log: log, category: ConstantsLog.categoryCGMG7, type: .info, sensorAgeInDays.description, maxSensorAgeInDays.description) + trace(" received g7GlucoseMessage mesage, sensorAge = %{public}@ / %{public}@", log: log, category: ConstantsLog.categoryCGMG7, type: .info, sensorAgeInDays.description, maxSensorAgeInDays > 0 ? maxSensorAgeInDays.description : "waiting...") sensorAge = g7GlucoseMessage.sensorAge @@ -376,10 +380,15 @@ class CGMG7Transmitter: BluetoothTransmitter, CGMTransmitter { func maxSensorAgeInDays() -> Double? { - if let transmitterIdString = UserDefaults.standard.activeSensorTransmitterId, transmitterIdString.startsWith("DX01") { - return ConstantsDexcomG7.maxSensorAgeInDaysStelo + if let transmitterIdString = UserDefaults.standard.activeSensorTransmitterId { + if transmitterIdString.startsWith("DX01") { + return ConstantsDexcomG7.maxSensorAgeInDaysStelo + } else { + return ConstantsDexcomG7.maxSensorAgeInDays + } } else { - return ConstantsDexcomG7.maxSensorAgeInDays + // if we haven't yet established the activeSensorTransmitterId (or device name) then return 0 - RVC will use this to know that we're still waiting + return 0 } } diff --git a/xdrip/BluetoothTransmitter/CGM/Generic/CGMTransmitter.swift b/xdrip/BluetoothTransmitter/CGM/Generic/CGMTransmitter.swift index 13d7f7b58..d5298f4e5 100644 --- a/xdrip/BluetoothTransmitter/CGM/Generic/CGMTransmitter.swift +++ b/xdrip/BluetoothTransmitter/CGM/Generic/CGMTransmitter.swift @@ -316,9 +316,11 @@ enum CGMTransmitterType:String, CaseIterable { return "Dexcom Stelo" } else if transmitterIdString.startsWith("DX02") { return "Dexcom ONE+" + } else { + return "Dexcom G7" } } - return "Dexcom G7" + return "Dexcom - please wait..." case .Libre2: if let activeSensorMaxSensorAgeInDays = UserDefaults.standard.activeSensorMaxSensorAgeInDays, activeSensorMaxSensorAgeInDays >= 15 { diff --git a/xdrip/Managers/ContactImage/ContactImageManager.swift b/xdrip/Managers/ContactImage/ContactImageManager.swift index 0d32400c8..0d3c9829b 100644 --- a/xdrip/Managers/ContactImage/ContactImageManager.swift +++ b/xdrip/Managers/ContactImage/ContactImageManager.swift @@ -81,9 +81,12 @@ class ContactImageManager: NSObject { // check that access to contacts is authorized by the user guard CNContactStore.authorizationStatus(for: .contacts) == .authorized else { - trace("in updateContact, access to contacts is not authorized, setting enableContactImage to false", log: self.log, category: ConstantsLog.categoryContactImageManager, type: .info) - - UserDefaults.standard.enableContactImage = false + // if it isn't, and the user has enabled the feature, then disable it + if UserDefaults.standard.enableContactImage { + trace("in updateContact, access to contacts is not authorized so setting enableContactImage to false", log: self.log, category: ConstantsLog.categoryContactImageManager, type: .info) + + UserDefaults.standard.enableContactImage = false + } return } @@ -124,7 +127,10 @@ class ContactImageManager: NSObject { // we'll search for all results and then just use the first one for now // we do it this way so that in the future we want to add a descriptor to the family name to have various contact images (such as "BG", "IOB", "COB" as needed) if let contacts = try? self.contactStore.unifiedContacts(matching: predicate, keysToFetch: keyToFetch), let contact = contacts.first { - trace("in updateContact, existing contact found. Updating it's contact image.", log: self.log, category: ConstantsLog.categoryContactImageManager, type: .info) + + if lastReading.count > 0 { + trace("in updateContact, '%{public}@' contact found. Updating the contact image to %{public}@ %{public}@.", log: self.log, category: ConstantsLog.categoryContactImageManager, type: .info, ConstantsHomeView.applicationName, lastReading[0].calculatedValue.mgDlToMmolAndToString(mgDl: UserDefaults.standard.bloodGlucoseUnitIsMgDl), UserDefaults.standard.bloodGlucoseUnitIsMgDl ? Texts_Common.mgdl : Texts_Common.mmol) + } // create a mutableContact from the existing contact so that we can modify it guard let mutableContact = contact.mutableCopy() as? CNMutableContact else { return } @@ -135,7 +141,7 @@ class ContactImageManager: NSObject { // we'll update the existing contact with the new data saveRequest.update(mutableContact) } else { - trace("in updateContact, no existing contact found. Creating a new contact called '%{public}@' and adding a contact image.", log: self.log, category: ConstantsLog.categoryContactImageManager, type: .info, ConstantsHomeView.applicationName) + trace("in updateContact, no existing contact found. Creating a new contact called '%{public}@' and adding a contact image with %{public}@ %{public}@.", log: self.log, category: ConstantsLog.categoryContactImageManager, type: .info, ConstantsHomeView.applicationName, lastReading[0].calculatedValue.mgDlToMmolAndToString(mgDl: UserDefaults.standard.bloodGlucoseUnitIsMgDl), UserDefaults.standard.bloodGlucoseUnitIsMgDl ? Texts_Common.mgdl : Texts_Common.mmol) // create a new mutable contact instance and assign properties to it let contact = CNMutableContact() diff --git a/xdrip/Utilities/Trace.swift b/xdrip/Utilities/Trace.swift index 22708eeba..18102af9b 100644 --- a/xdrip/Utilities/Trace.swift +++ b/xdrip/Utilities/Trace.swift @@ -366,9 +366,9 @@ class Trace { traceInfo.appendStringAndNewLine("\nNotifications settings:") traceInfo.appendStringAndNewLine(" Show BG in notifications: " + UserDefaults.standard.showReadingInNotification.description) traceInfo.appendStringAndNewLine(" Notification interval: " + UserDefaults.standard.notificationInterval.description + " minutes") - traceInfo.appendStringAndNewLine(" Live Activities Type: " + UserDefaults.standard.liveActivityType.debugDescription) + traceInfo.appendStringAndNewLine(" Live Activity type: " + UserDefaults.standard.liveActivityType.debugDescription) traceInfo.appendStringAndNewLine(" Show BG in app badge: " + UserDefaults.standard.showReadingInAppBadge.description) - traceInfo.appendStringAndNewLine(" Multiply app badge by 10: " + (UserDefaults.standard.bloodGlucoseUnitIsMgDl ? "-" : UserDefaults.standard.multipleAppBadgeValueWith10.description)) + traceInfo.appendStringAndNewLine(" Multiply app badge by 10: " + (UserDefaults.standard.bloodGlucoseUnitIsMgDl ? "\(UserDefaults.standard.multipleAppBadgeValueWith10.description) (but not used in mg/dL)" : UserDefaults.standard.multipleAppBadgeValueWith10.description)) traceInfo.appendStringAndNewLine("\nHome screen settings:") traceInfo.appendStringAndNewLine(" Allow chart rotation: " + UserDefaults.standard.allowScreenRotation.description) @@ -379,6 +379,8 @@ class Trace { traceInfo.appendStringAndNewLine(" Target: " + UserDefaults.standard.targetMarkValueInUserChosenUnitRounded.description) traceInfo.appendStringAndNewLine(" Low: " + UserDefaults.standard.lowMarkValueInUserChosenUnitRounded.description) traceInfo.appendStringAndNewLine(" Urgent low: " + UserDefaults.standard.urgentLowMarkValueInUserChosenUnitRounded.description) + traceInfo.appendStringAndNewLine(" Hours to show on main chart: " + UserDefaults.standard.chartWidthInHours.description) + traceInfo.appendStringAndNewLine(" Hours to show on mini-chart: " + UserDefaults.standard.miniChartHoursToShow.description) traceInfo.appendStringAndNewLine("\nTreatments settings:") traceInfo.appendStringAndNewLine(" Show treatments: " + UserDefaults.standard.showTreatmentsOnChart.description) @@ -388,6 +390,7 @@ class Trace { traceInfo.appendStringAndNewLine("\nStatistics settings:") traceInfo.appendStringAndNewLine(" Show statistics: " + UserDefaults.standard.showStatistics.description) + traceInfo.appendStringAndNewLine(" Statistics days: " + UserDefaults.standard.daysToUseStatistics.description) traceInfo.appendStringAndNewLine(" Time in Range type: " + UserDefaults.standard.timeInRangeType.description) traceInfo.appendStringAndNewLine(" Show HbA1c in mmols/mol: " + UserDefaults.standard.useIFCCA1C.description) @@ -397,11 +400,7 @@ class Trace { traceInfo.appendStringAndNewLine(" URL: " + ((UserDefaults.standard.nightscoutUrl?.description ?? "") != "" ? "present" : "missing")) traceInfo.appendStringAndNewLine(" API_SECRET: " + ((UserDefaults.standard.nightscoutAPIKey?.description ?? "") != "" ? "present" : "missing")) traceInfo.appendStringAndNewLine(" Token: " + ((UserDefaults.standard.nightscoutToken?.description ?? "") != "" ? "present" : "missing")) - if UserDefaults.standard.nightscoutPort != 0 { - traceInfo.appendStringAndNewLine(" Port: " + UserDefaults.standard.nightscoutPort.description) - } else { - traceInfo.appendStringAndNewLine(" Port: Missing") - } + traceInfo.appendStringAndNewLine(" Port: " + ((UserDefaults.standard.nightscoutPort != 0) ? UserDefaults.standard.nightscoutPort.description : " missing")) } traceInfo.appendStringAndNewLine("\nDexcom Share settings:") @@ -450,8 +449,9 @@ class Trace { } traceInfo.appendStringAndNewLine("\nContact Image settings:") - traceInfo.appendStringAndNewLine(" Create contact: " + UserDefaults.standard.enableContactImage.description) + traceInfo.appendStringAndNewLine(" Enable contact image: " + UserDefaults.standard.enableContactImage.description) traceInfo.appendStringAndNewLine(" Show trend: " + UserDefaults.standard.displayTrendInContactImage.description) + traceInfo.appendStringAndNewLine(" Use high contrast: " + UserDefaults.standard.useHighContrastContactImage.description) traceInfo.appendStringAndNewLine("\nData management settings:") traceInfo.appendStringAndNewLine(" Retention period: " + UserDefaults.standard.retentionPeriodInDays.description + " days") @@ -461,11 +461,14 @@ class Trace { traceInfo.appendStringAndNewLine(" Show developer settings: " + UserDefaults.standard.showDeveloperSettings.description) traceInfo.appendStringAndNewLine(" NS log enabled: " + UserDefaults.standard.NSLogEnabled.description) traceInfo.appendStringAndNewLine(" OS log enabled: " + UserDefaults.standard.OSLogEnabled.description) - traceInfo.appendStringAndNewLine(" Smooth Libre readings: " + UserDefaults.standard.smoothLibreValues.description) traceInfo.appendStringAndNewLine(" Suppress unlock payload: " + UserDefaults.standard.suppressUnLockPayLoad.description) traceInfo.appendStringAndNewLine(" OS-AID share type: " + UserDefaults.standard.loopShareType.description) traceInfo.appendStringAndNewLine(" LibreLinkUp version: " + (UserDefaults.standard.libreLinkUpVersion?.description ?? "nil")) + // misc settings + traceInfo.appendStringAndNewLine("\nMisc settings:") + traceInfo.appendStringAndNewLine(" Use debug level logs: " + UserDefaults.standard.addDebugLevelLogsInTraceFileAndNSLog.description) + traceInfo.appendStringAndNewLine(paragraphSeperator) traceInfo.appendStringAndNewLine("General flags/variables:\n") @@ -485,7 +488,7 @@ class Trace { } else { traceInfo.appendStringAndNewLine(" Sensor start date: nil") } - traceInfo.appendStringAndNewLine(" Sensor max days: " + (Int(UserDefaults.standard.activeSensorMaxSensorAgeInDays ?? 0)).description) + traceInfo.appendStringAndNewLine(" Sensor max days: " + (UserDefaults.standard.activeSensorMaxSensorAgeInDays ?? 0).description) traceInfo.appendStringAndNewLine(" Transmitter ID: " + (UserDefaults.standard.activeSensorTransmitterId?.description ?? "nil")) } else { traceInfo.appendStringAndNewLine(" Not used in Nightscout follower mode") @@ -504,10 +507,10 @@ class Trace { let alertTypesAccessor = AlertTypesAccessor(coreDataManager: coreDataManager) // all bluetooth transmitters - traceInfo.appendStringAndNewLine("List of Bluetooth Peripherals:\n") + traceInfo.appendStringAndNewLine("List of Bluetooth Peripherals:") for blePeripheral in bLEPeripheralAccessor.getBLEPeripherals() { - traceInfo.appendStringAndNewLine(" Name: " + blePeripheral.name) + traceInfo.appendStringAndNewLine("\n Name: " + blePeripheral.name) traceInfo.appendStringAndNewLine(" Address: " + blePeripheral.address) if let alias = blePeripheral.alias { traceInfo.appendStringAndNewLine(" Alias: " + alias) @@ -642,6 +645,7 @@ class Trace { if blePeripheral.libre2 != nil { traceInfo.appendStringAndNewLine(" Type: " + bluetoothPeripheralType.rawValue) + traceInfo.appendStringAndNewLine(" Smooth Libre readings: " + UserDefaults.standard.smoothLibreValues.description) } diff --git a/xdrip/View Controllers/Root View Controller/RootViewController.swift b/xdrip/View Controllers/Root View Controller/RootViewController.swift index 016da0869..317aee22e 100644 --- a/xdrip/View Controllers/Root View Controller/RootViewController.swift +++ b/xdrip/View Controllers/Root View Controller/RootViewController.swift @@ -3102,16 +3102,11 @@ final class RootViewController: UIViewController, ObservableObject { // check if there is a transmitter connected (needed as Dexcom will only connect briefly every 5 minutes) // if there is a transmitter connected, pull the current maxSensorAgeInDays and store in in UserDefaults if let cgmTransmitter = self.bluetoothPeripheralManager?.getCGMTransmitter(), let maxDays = cgmTransmitter.maxSensorAgeInDays() { - - if maxDays > 0 { - UserDefaults.standard.activeSensorMaxSensorAgeInDays = maxDays - } - + UserDefaults.standard.activeSensorMaxSensorAgeInDays = maxDays UserDefaults.standard.activeSensorDescription = cgmTransmitter.cgmTransmitterType().detailedDescription() // update the sensor type - needed to make sure we test with the correct warm-up times later sensorType = cgmTransmitter.cgmTransmitterType().sensorType() - } // let's just check that we've got enough information to display the view diff --git a/xdrip/View Controllers/Treatments/TreatmentTableViewCell.swift b/xdrip/View Controllers/Treatments/TreatmentTableViewCell.swift index 8cbb0c13f..dc2c88af6 100644 --- a/xdrip/View Controllers/Treatments/TreatmentTableViewCell.swift +++ b/xdrip/View Controllers/Treatments/TreatmentTableViewCell.swift @@ -40,6 +40,9 @@ class TreatmentTableViewCell: UITableViewCell { case .BgCheck: self.iconImageView.tintColor = ConstantsGlucoseChart.bgCheckTreatmentColorInner + default: + self.iconImageView.tintColor = nil + } switch treatment.treatmentType { @@ -56,6 +59,9 @@ class TreatmentTableViewCell: UITableViewCell { case .BgCheck: self.iconImageView.image = UIImage(systemName: "drop.fill") ?? nil + default: + self.iconImageView.tintColor = nil + } // treatment type label