startsensor works

This commit is contained in:
Johan Degraeve 2021-11-28 21:29:46 +01:00
parent dd794b25f3
commit df57b8fb5e
14 changed files with 310 additions and 72 deletions

View File

@ -229,6 +229,8 @@
F825286A2443AE190067AF77 /* DexcomG6BluetoothPeripheralViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F82528692443AE190067AF77 /* DexcomG6BluetoothPeripheralViewModel.swift */; };
F825286C2443BEDC0067AF77 /* CGMG6TransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F825286B2443BEDC0067AF77 /* CGMG6TransmitterDelegate.swift */; };
F8284230274ED56A0097E0C9 /* DexcomCalibrationParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = F828422F274ED56A0097E0C9 /* DexcomCalibrationParameters.swift */; };
F82842322752CBE00097E0C9 /* DexcomSessionStopTxMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = F82842312752CBE00097E0C9 /* DexcomSessionStopTxMessage.swift */; };
F82842352753D0340097E0C9 /* CGMG6FireflyTransmitter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F82842342753D0340097E0C9 /* CGMG6FireflyTransmitter.swift */; };
F8297F4E238DCAD800D74D66 /* BluetoothPeripheralsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8297F4B238DCAD800D74D66 /* BluetoothPeripheralsViewController.swift */; };
F8297F4F238DCAD800D74D66 /* BluetoothPeripheralNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8297F4C238DCAD800D74D66 /* BluetoothPeripheralNavigationController.swift */; };
F8297F52238ECA3200D74D66 /* BluetoothPeripheralViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8297F51238ECA3200D74D66 /* BluetoothPeripheralViewController.swift */; };
@ -1034,6 +1036,8 @@
F82528692443AE190067AF77 /* DexcomG6BluetoothPeripheralViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexcomG6BluetoothPeripheralViewModel.swift; sourceTree = "<group>"; };
F825286B2443BEDC0067AF77 /* CGMG6TransmitterDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGMG6TransmitterDelegate.swift; sourceTree = "<group>"; };
F828422F274ED56A0097E0C9 /* DexcomCalibrationParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexcomCalibrationParameters.swift; sourceTree = "<group>"; };
F82842312752CBE00097E0C9 /* DexcomSessionStopTxMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexcomSessionStopTxMessage.swift; sourceTree = "<group>"; };
F82842342753D0340097E0C9 /* CGMG6FireflyTransmitter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGMG6FireflyTransmitter.swift; sourceTree = "<group>"; };
F8297F4B238DCAD800D74D66 /* BluetoothPeripheralsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BluetoothPeripheralsViewController.swift; sourceTree = "<group>"; };
F8297F4C238DCAD800D74D66 /* BluetoothPeripheralNavigationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BluetoothPeripheralNavigationController.swift; sourceTree = "<group>"; };
F8297F51238ECA3200D74D66 /* BluetoothPeripheralViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BluetoothPeripheralViewController.swift; sourceTree = "<group>"; };
@ -1829,6 +1833,15 @@
path = DexcomG6;
sourceTree = "<group>";
};
F82842332753CFED0097E0C9 /* G6Firefly */ = {
isa = PBXGroup;
children = (
F82842342753D0340097E0C9 /* CGMG6FireflyTransmitter.swift */,
);
name = G6Firefly;
path = Generic/G6Firefly;
sourceTree = "<group>";
};
F8297F42238DC4AC00D74D66 /* BluetoothPeripheral */ = {
isa = PBXGroup;
children = (
@ -2683,6 +2696,7 @@
F8F971CE23A5915900C3F17D /* TransmitterVersionRxMessage.swift */,
F8F971C123A5915900C3F17D /* TransmitterVersionTxMessage.swift */,
F828422F274ED56A0097E0C9 /* DexcomCalibrationParameters.swift */,
F82842312752CBE00097E0C9 /* DexcomSessionStopTxMessage.swift */,
);
path = Generic;
sourceTree = "<group>";
@ -2774,11 +2788,12 @@
F8F971BB23A5915900C3F17D /* Dexcom */ = {
isa = PBXGroup;
children = (
F8F1670F27274067001AA3D8 /* Generic */,
F8F971BC23A5915900C3F17D /* G6 */,
F8F971BE23A5915900C3F17D /* G5 */,
F8F971D423A5915900C3F17D /* G4 */,
F8AF11F924B1FB3500AE5BA2 /* DexcomError.swift */,
F8F971D423A5915900C3F17D /* G4 */,
F8F971BE23A5915900C3F17D /* G5 */,
F8F971BC23A5915900C3F17D /* G6 */,
F82842332753CFED0097E0C9 /* G6Firefly */,
F8F1670F27274067001AA3D8 /* Generic */,
);
path = Dexcom;
sourceTree = "<group>";
@ -3431,6 +3446,7 @@
F808D2CE2403292C0084B5DB /* Bubble+CoreDataProperties.swift in Sources */,
F8A2BC1A25DB0C28001D1E78 /* CGMAtomTransmitterDelegate.swift in Sources */,
F816E1002436734C009EE65B /* CGMGNSEntryTransmitterDelegate.swift in Sources */,
F82842322752CBE00097E0C9 /* DexcomSessionStopTxMessage.swift in Sources */,
F8C97853242AA70D00A09483 /* MiaoMiao+CoreDataClass.swift in Sources */,
F8F9720D23A5915900C3F17D /* ResetMessage.swift in Sources */,
F85FF3D7252FB1C0004E6FF1 /* SnoozeParametersAccessor.swift in Sources */,
@ -3575,6 +3591,7 @@
F8F1671927288FC6001AA3D8 /* DexcomSessionStartRxMessage.swift in Sources */,
F804870D2336D90200EBDDB7 /* M5Stack+CoreDataProperties.swift in Sources */,
F85FF3CD252F9FD7004E6FF1 /* SnoozeParameters+CoreDataProperties.swift in Sources */,
F82842352753D0340097E0C9 /* CGMG6FireflyTransmitter.swift in Sources */,
F8F9722F23A5915900C3F17D /* M5StackPacket.swift in Sources */,
F821CF8E22AB090C005C1E43 /* DatePickerViewController.swift in Sources */,
F8AF11F324B1279500AE5BA2 /* TextsLibreErrors.swift in Sources */,

View File

@ -1,9 +1,10 @@
import Foundation
import xDrip4iOS_Widget
extension DexcomG5: BluetoothPeripheral {
func bluetoothPeripheralType() -> BluetoothPeripheralType {
if isDexcomG6 {return .DexcomG6Type}
if isFirefly {return .DexcomG6FireflyType}

View File

@ -152,10 +152,10 @@ enum BluetoothPeripheralType: String, CaseIterable {
// which means, a user could add a Dexcom G6 Firefly as a Dexcom G6 or even a Dexcom G5, the class CGMG5Transmitter will find out it's a firefly, based on transmitter id and handle it as a firefly
// It plays only a role in the RootViewController that a G6 Firefly is selected, because then also the user needs to add a code
let dexcomG6 = DexcomG5(address: address, name: name, alias: nil, nsManagedObjectContext: nsManagedObjectContext)
dexcomG6.isFirefly = true
let dexcomG6Firefly = DexcomG5(address: address, name: name, alias: nil, nsManagedObjectContext: nsManagedObjectContext)
dexcomG6Firefly.isFirefly = true
return dexcomG6
return dexcomG6Firefly
case .BubbleType:

View File

@ -16,6 +16,9 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
/// created public because inheriting classes need it
var transmitterStartDate: Date?
/// if true, then firefly flow will be used, even if the transmitter id < 8G
var isFireflyNoMatterTransmitterId: Bool = false
/// CGMG5TransmitterDelegate
public weak var cGMG5TransmitterDelegate: CGMG5TransmitterDelegate?
@ -131,12 +134,17 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
/// if the user starts the sensor via xDrip4iOS, then only after having receivec a confirmation from the transmitter, then sensorStartDate will be assigned to the actual sensor start date
private var sensorStartDate: Date?
/// to temporary store the received SensorStartDate. Will be compared to sensorStartDate only after having received a glucoseRx message with a valid algorithm status
private var receivedSensorStartDate: Date?
/// - used to send sensor start done by user via xDrip4iOS to Dexcom transmitter. For example, user may have started a sensor in the app, but it's not yet send to the transmitter.
/// - tuple consisitng of startDate and dexcomCalibrationParameters. If startDate is nil, then there's no start sensor waiting to be sent to the transmitter.
private var sensorStartToSendToTransmitter: (startDate: Date, dexcomCalibrationParameters: DexcomCalibrationParameters)?
/// if true, then firefly flow will be used, even if the transmitter id < 8G
private let isFireflyNoMatterTransmitterId: Bool
/// used to send stop session to transmitter
private var dexcomSessionStopTxMessageToSendToTransmitter: DexcomSessionStopTxMessage?
private var timeStampLastConnection = Date(timeIntervalSince1970: 0)
// MARK: - public functions
@ -150,8 +158,7 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
/// - transmitterStartDate : transmitter start date, optional - actual transmitterStartDate is received from transmitter itself, and stored in coredata. The stored value iss given here as parameter in the initializer. Means at app start up, it's read from core data and added here as parameter
/// - sensorStartDate : should be sensorStartDate of active sensor. If a different sensor start date is received from the transmitter, then we know a new senosr was started
/// - calibrationToSendToTransmitter : used to send calibration done by user via xDrip4iOS to Dexcom transmitter. For example, user may have give a calibration in the app, but it's not yet send to the transmitter. This needs to be verified in CGMG5Transmitter, which is why it's given here as parameter - when initializing, assign last known calibration for the active sensor, even if it's already sent.
/// - isFireFly : if true then the transmitter will be treated as a firefly, no matter the transmitter id, no matter if it's a G5, G6 or real Firefly
init(address:String?, name: String?, transmitterID:String, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate, cGMG5TransmitterDelegate: CGMG5TransmitterDelegate, cGMTransmitterDelegate:CGMTransmitterDelegate, transmitterStartDate: Date?, sensorStartDate: Date?, calibrationToSendToTransmitter: Calibration?, firmware: String?, isFireFly: Bool) {
init(address:String?, name: String?, transmitterID:String, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate, cGMG5TransmitterDelegate: CGMG5TransmitterDelegate, cGMTransmitterDelegate:CGMTransmitterDelegate, transmitterStartDate: Date?, sensorStartDate: Date?, calibrationToSendToTransmitter: Calibration?, firmware: String?) {
// assign addressname and name or expected devicename
var newAddressAndName:BluetoothTransmitter.DeviceAddressAndName = BluetoothTransmitter.DeviceAddressAndName.notYetConnected(expectedName: "DEXCOM" + transmitterID[transmitterID.index(transmitterID.startIndex, offsetBy: 4)..<transmitterID.endIndex])
@ -174,9 +181,6 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
// assign sensorStartDate
self.sensorStartDate = sensorStartDate
// assign isFireflyNoMatterTransmitterId
self.isFireflyNoMatterTransmitterId = isFireFly
// initialize - CBUUID_Receive_Authentication.rawValue and CBUUID_Write_Control.rawValue will probably not be used in the superclass
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: CBUUID_Advertisement_G5, servicesCBUUIDs: [CBUUID(string: CBUUID_Service_G5)], CBUUID_ReceiveCharacteristic: CBUUID_Characteristic_UUID.CBUUID_Receive_Authentication.rawValue, CBUUID_WriteCharacteristic: CBUUID_Characteristic_UUID.CBUUID_Write_Control.rawValue, bluetoothTransmitterDelegate: bluetoothTransmitterDelegate)
@ -271,7 +275,7 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
// get characteristic description and trace
var characteristicDescription = characteristic.uuid.uuidString
if let characteristic = CBUUID_Characteristic_UUID(rawValue: characteristic.uuid.uuidString) { characteristicDescription = characteristic.description}
trace("in peripheralDidUpdateNotificationStateFor. characteristic = ", log: log, category: ConstantsLog.categoryCGMG5, type: .info, characteristicDescription)
trace("in peripheralDidUpdateNotificationStateFor. characteristic = %{public}@", log: log, category: ConstantsLog.categoryCGMG5, type: .info, characteristicDescription)
if let error = error {
trace(" error: %{public}@", log: log, category: ConstantsLog.categoryCGMG5, type: .error , error.localizedDescription)
@ -395,6 +399,7 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
// subscribe to writeControlCharacteristic
if let writeControlCharacteristic = writeControlCharacteristic {
trace(" will set notifyValue for writeControlCharacteristic to true", log: log, category: ConstantsLog.categoryCGMG5, type: .error)
setNotifyValue(true, for: writeControlCharacteristic)
} else {
@ -404,12 +409,11 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
// subscribe to backfillCharacteristic
if let backfillCharacteristic = backfillCharacteristic {
trace(" will set notifyValue for backfillCharacteristic to true", log: log, category: ConstantsLog.categoryCGMG5, type: .error)
setNotifyValue(true, for: backfillCharacteristic)
} else {
trace(" backfillCharacteristic is nil, can not set notifyValue", log: log, category: ConstantsLog.categoryCGMG5, type: .error)
}
}
@ -594,6 +598,9 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
case .sessionStopRx:
processSessionStopRxMessage(value: value)
// if firefly continue with the firefly message flow
if useFireflyFlow() { fireflyMessageFlow() }
case .sessionStartRx:
@ -637,16 +644,32 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
// not calling super.didconnect here
// if last reading was less than a minute ago, then no need to continue, otherwise continue with process by calling super.centralManager(central, didConnect: peripheral)
if Date() < Date(timeInterval: ConstantsDexcomG5.minimumTimeBetweenTwoReadings, since: timeStampOfLastG5Reading) {
trace("connected to peripheral with name %{public}@, but last reading was less than %{public}@ minute ago", log: log, category: ConstantsLog.categoryCGMG5, type: .info, (deviceName != nil ? deviceName! : "unknown"), ConstantsDexcomG5.minimumTimeBetweenTwoReadings.minutes.description)
// don't disconnect here, keep the connection open, the transmitter will disconnect in a few seconds, assumption is that this will increase battery life
} else {
// if last reading was less than 2.1 minutes ago, or last connection less than 2.1 minutes ago, then no need to continue, otherwise continue with process by calling super.centralManager(central, didConnect: peripheral)
// except if calibrationToSendToTransmitter or sensorStartToSendToTransmitter or dexcomSessionStopTxMessageToSendTransmitter not nil
if calibrationToSendToTransmitter == nil && sensorStartToSendToTransmitter == nil && dexcomSessionStopTxMessageToSendToTransmitter == nil {
super.centralManager(central, didConnect: peripheral)
if Date() < Date(timeInterval: ConstantsDexcomG5.minimumTimeBetweenTwoReadings, since: timeStampOfLastG5Reading) {
trace("connected to peripheral with name %{public}@, but last reading was less than %{public}@ minute ago, will let the connection timeout", log: log, category: ConstantsLog.categoryCGMG5, type: .info, (deviceName != nil ? deviceName! : "unknown"), ConstantsDexcomG5.minimumTimeBetweenTwoReadings.minutes.description)
// don't disconnect here, keep the connection open, the transmitter will disconnect in a few seconds, assumption is that this will increase battery life, because otherwise there's lot of unnecessary data communication
return
} else if Date() < Date(timeInterval: TimeInterval(minutes: 2.1), since: timeStampLastConnection) {
trace("connected to peripheral with name %{public}@, but last connection was less than 2.1 minutes ago, will let the connection timeout", log: log, category: ConstantsLog.categoryCGMG5, type: .info, (deviceName != nil ? deviceName! : "unknown"))
// don't disconnect here, keep the connection open, the transmitter will disconnect in a few seconds, assumption is that this will increase battery life, because otherwise there's lot of unnecessary data communication
return
}
}
super.centralManager(central, didConnect: peripheral)
timeStampLastConnection = Date()
// to be sure waitingPairingConfirmation is reset to false
waitingPairingConfirmation = false
@ -729,25 +752,54 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
return useFireflyFlow()
}
func startSensor(dexcomCalibrationParameters: DexcomCalibrationParameters, startDate: Date) {
func startSensor(sensorCode: String?, startDate: Date) {
// assign sensorStartToSendToTransmitter to nil, because a new sensor start command must be sent
sensorStartToSendToTransmitter = nil
guard startDate != sensorStartDate else {
trace("in startSensor, but startDate is equal to already known sensorStartDate, so it looks as if a startSensor is done for a sensor that is already started. No further processing", log: log, category: ConstantsLog.categoryCGMG5, type: .info)
return
}
guard let dexcomCalibrationParameters = DexcomCalibrationParameters(sensorCode: sensorCode) else {
trace("in startSensor, failed to create dexcomCalibrationParameters for sensorcode %{public}@", log: log, category: ConstantsLog.categoryCGMG5, type: .info, (sensorCode == nil ? "nil" : sensorCode!))
return
}
trace("in startSensor, storing sensor start info, will be sent to transmitter at next connect", log: log, category: ConstantsLog.categoryCGMG5, type: .info)
// assign sensorStartToSendToTransmitter
sensorStartToSendToTransmitter = (startDate, dexcomCalibrationParameters)
}
func stopSensor(stopDate: Date) {
// if there's no sensorStartDate known, then don't send any stopSensor command to the transmitter
if sensorStartDate == nil {
trace("in stopSensor, sensorStartDate is nil, no further processing", log: log, category: ConstantsLog.categoryCGMG5, type: .info)
return
}
guard let transmitterStartDate = transmitterStartDate else { return }
trace("in stopsensor, storing sensor stop info, will be sent to transmitter at next connect", log: log, category: ConstantsLog.categoryCGMG5, type: .info)
dexcomSessionStopTxMessageToSendToTransmitter = DexcomSessionStopTxMessage(stopDate: stopDate, transmitterStartDate: transmitterStartDate)
}
func calibrate(calibration: Calibration?) {
// - if calibration is valid, then it assigns calibrationToSendToTransmitter to calibration, will be picked up when transmitter connects , and if it's within an hour
@ -871,6 +923,22 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
}
private func sendSessionStopTxMessage(dexcomSessionStopTxMessage: DexcomSessionStopTxMessage) {
if let writeControlCharacteristic = writeControlCharacteristic {
trace("sending sendSessionStopTxMessage with stopDate %{public}@", log: log, category: ConstantsLog.categoryCGMG5, type: .info, dexcomSessionStopTxMessage.stopDate.toString(timeStyle: .long, dateStyle: .long))
_ = super.writeDataToPeripheral(data: dexcomSessionStopTxMessage.data, characteristicToWriteTo: writeControlCharacteristic, type: .withResponse)
} else {
trace("in sendSessionStopTxMessage, writeControlCharacteristic is nil", log: log, category: ConstantsLog.categoryCGMG5, type: .error)
}
}
/// sends startDate and dexcomCalibrationParameters to transmitter. Will use super.writeDataToPeripheral, meaning, even if letDexcomAppDoTheTransmitWork = true, then still it will send the data to the transmitter
private func sendSessionStartTxMessage(sensorStartToSendToTransmitter: (startDate: Date, dexcomCalibrationParameters: DexcomCalibrationParameters), transmitterStartDate: Date) {
@ -1002,10 +1070,12 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
if let dexcomSessionStopRxMessage = DexcomSessionStopRxMessage(data: value) {
trace("in processSessionStopRxMessage, received dexcomSessionStopRxMessage, isOkay = %{public}@, received = %{public}@, sessionStartTime = %{public}@, sessionStopTime = %{public}@, status = %{public}@, transmitterTime = %{public}@,", log: log, category: ConstantsLog.categoryCGMG5, type: .info, dexcomSessionStopRxMessage.isOkay.description, dexcomSessionStopRxMessage.sessionStopResponse.description, dexcomSessionStopRxMessage.sessionStartTime.description, dexcomSessionStopRxMessage.sessionStopTime.description, dexcomSessionStopRxMessage.status.description, dexcomSessionStopRxMessage.transmitterTime.description)
trace("in processSessionStopRxMessage, received dexcomSessionStopRxMessage, isOkay = %{public}@, sessionStopResponse = %{public}@, sessionStartTime = %{public}@, sessionStopTime = %{public}@, status = %{public}@, transmitterTime = %{public}@,", log: log, category: ConstantsLog.categoryCGMG5, type: .info, dexcomSessionStopRxMessage.isOkay.description, dexcomSessionStopRxMessage.sessionStopResponse.description, dexcomSessionStopRxMessage.sessionStopDate.toString(timeStyle: .long, dateStyle: .long), dexcomSessionStopRxMessage.sessionStopTime.description, dexcomSessionStopRxMessage.status.description, dexcomSessionStopRxMessage.transmitterStartDate.toString(timeStyle: .long, dateStyle: .long))
} else {
trace("dexcomSessionStopRxMessage is nil", log: log, category: ConstantsLog.categoryCGMG5, type: .error)
}
}
@ -1084,9 +1154,38 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
// create glucose data and assign to lastGlucoseInSensorDataRxReading
lastGlucoseInSensorDataRxReading = GlucoseData(timeStamp: timeStamp, glucoseLevelRaw: calculatedValue)
// this is a valid sensor state, now it's time to process receivedSensorStartDate if it exists
if let receivedSensorStartDate = receivedSensorStartDate {
// if current sensorStartDate is < from receivedSensorStartDate then it seems a new sensor
if sensorStartDate == nil || (sensorStartDate! < receivedSensorStartDate) {
trace(" Seems a new sensor is detected.", log: log, category: ConstantsLog.categoryCGMG5, type: .info)
self.receivedSensorStartDate = receivedSensorStartDate
cgmTransmitterDelegate?.newSensorDetected(sensorStartDate: receivedSensorStartDate)
}
// assign sensorStartDate to receivedSensorStartDate
sensorStartDate = receivedSensorStartDate
// reset receivedSensorStartDate to nil
self.receivedSensorStartDate = nil
}
break
case .SessionStopped:
// session stopped, means sensor stopped?
cgmTransmitterDelegate?.sensorStopDetected()
sensorStartDate = nil
default:
trace(" algorithm state is %{public}@, not creating last glucoseData", log: log, category: ConstantsLog.categoryCGMG5, type: .info, algorithmStatus.description)
@ -1156,15 +1255,12 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
// if current sensorStartDate is < from receivedSensorStartDate then it seems a new sensor
if sensorStartDate == nil || (sensorStartDate! < receivedSensorStartDate) {
trace(" sensorStartDate == nil or sensorStartDate < receivedSensorStartDate, seems a new sensor is detected.", log: log, category: ConstantsLog.categoryCGMG5, type: .info)
trace(" current sensorStartDate == nil or current sensorStartDate < received SensorStartDate, seems a new sensor is detected. Temporary storing the received SensorStartDate till a glucoseRx message is received with valid sensor status", log: log, category: ConstantsLog.categoryCGMG5, type: .info)
cgmTransmitterDelegate?.newSensorDetected(sensorStartDate: receivedSensorStartDate)
self.receivedSensorStartDate = receivedSensorStartDate
}
// assign sensorStartDate to receivedSensorStartDate
sensorStartDate = receivedSensorStartDate
} else {
trace(" sensorStartDate is nil", log: log, category: ConstantsLog.categoryCGMG5, type: .info)
}
@ -1324,6 +1420,8 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
// first of all check that the transmitter is really a firefly, if not stop processing
if !useFireflyFlow() { return }
trace(" start of firefly flow", log: log, category: ConstantsLog.categoryCGMG5, type: .info)
// check if firmware is known, if not ask it
guard firmware != nil else {
@ -1337,14 +1435,34 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
// if yes, request battery status (done in function batteryStatusRequested)
if !batteryStatusRequested() {
// check if transmitterStartDate is known, and if we've recently requested the sensorStartTime, if not then request transmitterStartDate, response should contain both transmitterStartDate and sensorStartDate
if let transmitterStartDate = transmitterStartDate, Date() < Date(timeInterval: ConstantsDexcomG5.sensorStartTimeReadPeriod, since: timeStampLastSensorStartTimeRead) {
// check if transmitterStartDate is known
// and if sensorStartTime is known:
// - check if we've recently requested the sensorStartTime, less than sensorStartTimeReadPeriod ago
// and if sensorStartTime is not known:
// - check if we've recently requested the sensorStartTime, less than 2.1 minutes ago
// otherwise get transmitterStartDate and sensorStartTime
if let transmitterStartDate = transmitterStartDate,
(
(Date() < Date(timeInterval: ConstantsDexcomG5.sensorStartTimeReadPeriod, since: timeStampLastSensorStartTimeRead) && sensorStartDate != nil)
||
(Date() < Date(timeInterval: TimeInterval(minutes: 2.1), since: timeStampLastSensorStartTimeRead) && sensorStartDate == nil)
) {
// if there's a sensor start command to send it
if let dexcomSessionStopTxMessage = dexcomSessionStopTxMessageToSendToTransmitter {
sendSessionStopTxMessage(dexcomSessionStopTxMessage: dexcomSessionStopTxMessage)
self.dexcomSessionStopTxMessageToSendToTransmitter = nil
} else
// if there's a sensor start command to send, then send it
if let sensorStartToSendToTransmitter = sensorStartToSendToTransmitter {
sendSessionStartTxMessage(sensorStartToSendToTransmitter: (startDate: sensorStartToSendToTransmitter.startDate, dexcomCalibrationParameters: sensorStartToSendToTransmitter.dexcomCalibrationParameters), transmitterStartDate: transmitterStartDate)
self.sensorStartToSendToTransmitter = nil
} else
// if there's a valid calibrationToSendToTransmitter
@ -1364,9 +1482,10 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
} else
// if glucoseTx was not yet sent and minimumTimeBetweenTwoReadings smaller than now - timeStampOfLastG5Reading (for safety)
// if glucoseTx was not yet sent and minimumTimeBetweenTwoReadings larger than now - timeStampOfLastG5Reading (for safety)
// then send glucoseTx message
if !glucoseTxSent || Date() < Date(timeInterval: ConstantsDexcomG5.minimumTimeBetweenTwoReadings, since: timeStampOfLastG5Reading) {
// and sensor must be active
if !glucoseTxSent && Date() > Date(timeInterval: ConstantsDexcomG5.minimumTimeBetweenTwoReadings, since: timeStampOfLastG5Reading) && sensorStartDate != nil {
// ask latest glucose value
sendGlucoseTxMessage()
@ -1381,7 +1500,8 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
// check if backfill needed, and request backfill if needed
// if not needed continue with flow
if Date().timeIntervalSince(timeStampOfLastG5Reading) > ConstantsDexcomG5.minPeriodOfLatestReadingsToStartBackFill && !backfillTxSent {
// sensor must be active
if Date().timeIntervalSince(timeStampOfLastG5Reading) > ConstantsDexcomG5.minPeriodOfLatestReadingsToStartBackFill && !backfillTxSent && sensorStartDate != nil {
// send backfillTxMessage
// start time = timeStampOfLastG5Reading - maximum maxBackfillPeriod
@ -1396,9 +1516,7 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
trace(" end of firefly flow", log: log, category: ConstantsLog.categoryCGMG5, type: .info)
// disconnect
trace(" will disconnect now", log: log, category: ConstantsLog.categoryCGMG5, type: .info)
disconnect()
trace(" will not disconnect, let transmitter timeout the connect", log: log, category: ConstantsLog.categoryCGMG5, type: .info)
}

View File

@ -12,11 +12,10 @@ class CGMG6Transmitter: CGMG5Transmitter {
/// - transmitterStartDate : transmitter start date, optional - actual transmitterStartDate is received from transmitter itself, and stored in coredata. The stored value iss given here as parameter in the initializer. Means at app start up, it's read from core data and added here as parameter
/// - sensorStartDate : if the user starts the sensor via xDrip4iOS, then only after having receivec a confirmation from the transmitter, then sensorStartDate will be assigned to the actual sensor start date
/// - calibrationToSendToTransmitter : used to send calibration done by user via xDrip4iOS to Dexcom transmitter. For example, user may have give a calibration in the app, but it's not yet send to the transmitter. This needs to be verified in CGMG5Transmitter, which is why it's given here as parameter - when initializing, assign last known calibration for the active sensor, even if it's already sent.
/// - isFireFly : if true then the transmitter will be treated as a firefly, no matter the transmitter id, no matter if it's a G5, G6 or real Firefly
init(address:String?, name: String?, transmitterID:String, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate, cGMG6TransmitterDelegate: CGMG6TransmitterDelegate, cGMTransmitterDelegate:CGMTransmitterDelegate, transmitterStartDate: Date?, sensorStartDate: Date?, calibrationToSendToTransmitter: Calibration?, firmware: String?, isFireFly: Bool) {
init(address:String?, name: String?, transmitterID:String, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate, cGMG6TransmitterDelegate: CGMG6TransmitterDelegate, cGMTransmitterDelegate:CGMTransmitterDelegate, transmitterStartDate: Date?, sensorStartDate: Date?, calibrationToSendToTransmitter: Calibration?, firmware: String?) {
// call super.init
super.init(address: address, name: name, transmitterID: transmitterID, bluetoothTransmitterDelegate: bluetoothTransmitterDelegate, cGMG5TransmitterDelegate: cGMG6TransmitterDelegate, cGMTransmitterDelegate: cGMTransmitterDelegate, transmitterStartDate: transmitterStartDate, sensorStartDate: sensorStartDate, calibrationToSendToTransmitter: calibrationToSendToTransmitter, firmware: firmware, isFireFly: isFireFly)
super.init(address: address, name: name, transmitterID: transmitterID, bluetoothTransmitterDelegate: bluetoothTransmitterDelegate, cGMG5TransmitterDelegate: cGMG6TransmitterDelegate, cGMTransmitterDelegate: cGMTransmitterDelegate, transmitterStartDate: transmitterStartDate, sensorStartDate: sensorStartDate, calibrationToSendToTransmitter: calibrationToSendToTransmitter, firmware: firmware)
}
@ -39,7 +38,9 @@ class CGMG6Transmitter: CGMG5Transmitter {
}
override func cgmTransmitterType() -> CGMTransmitterType {
return .dexcomG6
}
}

View File

@ -15,12 +15,21 @@ struct DexcomSessionStopRxMessage {
let sessionStopResponse: DexcomSessionStopResponse
/// timeinterval since transmitterStartDate
let sessionStopTime: Double
/// timeinterval since transmitterStartDate
let sessionStartTime: Double
/// transmitterStartDAte =timeinterval since now, negative
let transmitterTime: Double
/// transmitter Start Date
let transmitterStartDate: Date
/// session stopDate
let sessionStopDate: Date
init?(data: Data) {
guard data.count >= 15 else { return nil }
@ -39,6 +48,10 @@ struct DexcomSessionStopRxMessage {
transmitterTime = Double(Data(data[11..<15]).to(UInt32.self))
transmitterStartDate = Date(timeIntervalSinceNow: -transmitterTime)
sessionStopDate = Date(timeInterval: sessionStopTime, since: transmitterStartDate)
}
var isOkay: Bool {

View File

@ -0,0 +1,38 @@
//
// DexcomG6SessionStartTxMessage.swift
// xDrip
//
// Created by Dmitry on 08.01.2021.
// Copyright © 2021 Faifly. All rights reserved.
//
import Foundation
struct DexcomSessionStopTxMessage: TransmitterTxMessage {
let data: Data
let stopDate: Date
init(stopDate: Date, transmitterStartDate: Date) {
self.stopDate = stopDate
var array = [Int8]()
array.append(Int8(DexcomTransmitterOpCode.sessionStopTx.rawValue))
let stopTime = Int(stopDate.timeIntervalSince1970 - transmitterStartDate.timeIntervalSince1970)
withUnsafeBytes(of: stopTime) {
array.append(contentsOf: Array($0.prefix(4 * MemoryLayout<Int8>.size)).map { Int8(bitPattern: $0) })
}
let data = array.withUnsafeBufferPointer { Data(buffer: $0) }
self.data = data.appendingCRC()
}
}

View File

@ -0,0 +1,30 @@
import Foundation
class CGMG6FireflyTransmitter: CGMG5Transmitter {
/// - parameters:
/// - address: if already connected before, then give here the address that was received during previous connect, if not give nil
/// - name : if already connected before, then give here the name that was received during previous connect, if not give nil
/// - transmitterID: expected transmitterID, 6 characters
/// - bluetoothTransmitterDelegate : a NluetoothTransmitterDelegate
/// - cGMTransmitterDelegate : a CGMTransmitterDelegate
/// - cGMG5TransmitterDelegate : a CGMG5TransmitterDelegate
/// - transmitterStartDate : transmitter start date, optional - actual transmitterStartDate is received from transmitter itself, and stored in coredata. The stored value iss given here as parameter in the initializer. Means at app start up, it's read from core data and added here as parameter
/// - sensorStartDate : if the user starts the sensor via xDrip4iOS, then only after having receivec a confirmation from the transmitter, then sensorStartDate will be assigned to the actual sensor start date
/// - calibrationToSendToTransmitter : used to send calibration done by user via xDrip4iOS to Dexcom transmitter. For example, user may have give a calibration in the app, but it's not yet send to the transmitter. This needs to be verified in CGMG5Transmitter, which is why it's given here as parameter - when initializing, assign last known calibration for the active sensor, even if it's already sent.
init(address:String?, name: String?, transmitterID:String, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate, cGMG6TransmitterDelegate: CGMG6TransmitterDelegate, cGMTransmitterDelegate:CGMTransmitterDelegate, transmitterStartDate: Date?, sensorStartDate: Date?, calibrationToSendToTransmitter: Calibration?, firmware: String?) {
// call super.init
super.init(address: address, name: name, transmitterID: transmitterID, bluetoothTransmitterDelegate: bluetoothTransmitterDelegate, cGMG5TransmitterDelegate: cGMG6TransmitterDelegate, cGMTransmitterDelegate: cGMTransmitterDelegate, transmitterStartDate: transmitterStartDate, sensorStartDate: sensorStartDate, calibrationToSendToTransmitter: calibrationToSendToTransmitter, firmware: firmware)
isFireflyNoMatterTransmitterId = true
}
override func cgmTransmitterType() -> CGMTransmitterType {
return .dexcomG6Firefly
}
}

View File

@ -9,6 +9,9 @@ protocol CGMTransmitterDelegate:AnyObject {
/// - detected sensor start time, optional, default nil
func newSensorDetected(sensorStartDate: Date?)
/// only for transmitters that can detect an expired sensor - only used for Firefly (at the time of writing this), but could probably also be used for Libre
func sensorStopDetected()
/// only for transmitters that can detect missing sensor
func sensorNotDetected()

View File

@ -248,7 +248,7 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
if let peripheral = peripheral, getConnectionStatus() == CBPeripheralState.connected {
trace("in writeDataToPeripheral, for peripheral with name %{public}@, for characteristic %{public}@", log: log, category: ConstantsLog.categoryBlueToothTransmitter, type: .info, deviceName ?? "'unknown'", characteristicToWriteTo.uuid.description)
trace("in writeDataToPeripheral, for peripheral with name %{public}@, for characteristic %{public}@, data = %{public}@", log: log, category: ConstantsLog.categoryBlueToothTransmitter, type: .info, deviceName ?? "'unknown'", characteristicToWriteTo.uuid.description, data.hexEncodedString())
peripheral.writeValue(data, for: characteristicToWriteTo, type: type)

View File

@ -9,7 +9,7 @@ enum ConstantsDexcomG5 {
static let maxTimeToAcceptPairing = TimeInterval(minutes: 1.0)
/// how often to read sensor start time (only for Firefly)
static let sensorStartTimeReadPeriod = TimeInterval(hours: 1.0)
static let sensorStartTimeReadPeriod = TimeInterval(hours: 0.5)
/// how far in history to go back for fetching readings
static let maxBackfillPeriod = TimeInterval(hours: 6.0)
@ -18,7 +18,7 @@ enum ConstantsDexcomG5 {
static let minPeriodOfLatestReadingsToStartBackFill = TimeInterval(minutes: 5.30)
/// if there's a new connect within this period, but latest reading was less than this interval ago, then no need to request new reading
static let minimumTimeBetweenTwoReadings = TimeInterval(minutes: 2.0)
static let minimumTimeBetweenTwoReadings = TimeInterval(minutes: 2.1)
/// specifically for firefly. If calibration was created more than this period ago, but not yet sent to the transmitter, then it will not be sent anymore
static let maxUnSentCalibrationAge = TimeInterval(minutes: 5)

View File

@ -173,14 +173,15 @@ class BluetoothPeripheralManager: NSObject {
// add it to the array of bluetoothTransmitters
if !dexcomG5orG6.isDexcomG6 && !dexcomG5orG6.isFirefly {
bluetoothTransmitters.insert(CGMG5Transmitter(address: dexcomG5orG6.blePeripheral.address, name: dexcomG5orG6.blePeripheral.name, transmitterID: transmitterId, bluetoothTransmitterDelegate: self, cGMG5TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, transmitterStartDate: dexcomG5orG6.transmitterStartDate, sensorStartDate: dexcomG5orG6.sensorStartDate, calibrationToSendToTransmitter: calibrationsAccessor.lastCalibrationForActiveSensor(withActivesensor: sensorsAccessor.fetchActiveSensor()), firmware: dexcomG5orG6.firmwareVersion, isFireFly: dexcomG5orG6.isFirefly), at: index)
bluetoothTransmitters.insert(CGMG5Transmitter(address: dexcomG5orG6.blePeripheral.address, name: dexcomG5orG6.blePeripheral.name, transmitterID: transmitterId, bluetoothTransmitterDelegate: self, cGMG5TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, transmitterStartDate: dexcomG5orG6.transmitterStartDate, sensorStartDate: dexcomG5orG6.sensorStartDate, calibrationToSendToTransmitter: calibrationsAccessor.lastCalibrationForActiveSensor(withActivesensor: sensorsAccessor.fetchActiveSensor()), firmware: dexcomG5orG6.firmwareVersion), at: index)
} else if !dexcomG5orG6.isFirefly {
bluetoothTransmitters.insert(CGMG6Transmitter(address: dexcomG5orG6.blePeripheral.address, name: dexcomG5orG6.blePeripheral.name, transmitterID: transmitterId, bluetoothTransmitterDelegate: self, cGMG6TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, transmitterStartDate: dexcomG5orG6.transmitterStartDate, sensorStartDate: dexcomG5orG6.sensorStartDate, calibrationToSendToTransmitter: calibrationsAccessor.lastCalibrationForActiveSensor(withActivesensor: sensorsAccessor.fetchActiveSensor()), firmware: dexcomG5orG6.firmwareVersion), at: index)
} else {
// CGMG6 transmitter is created for G6 or Firefly
// in the end for firefly we could as wel create it as a G5
bluetoothTransmitters.insert(CGMG6Transmitter(address: dexcomG5orG6.blePeripheral.address, name: dexcomG5orG6.blePeripheral.name, transmitterID: transmitterId, bluetoothTransmitterDelegate: self, cGMG6TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, transmitterStartDate: dexcomG5orG6.transmitterStartDate, sensorStartDate: dexcomG5orG6.sensorStartDate, calibrationToSendToTransmitter: calibrationsAccessor.lastCalibrationForActiveSensor(withActivesensor: sensorsAccessor.fetchActiveSensor()), firmware: dexcomG5orG6.firmwareVersion, isFireFly: dexcomG5orG6.isFirefly), at: index)
bluetoothTransmitters.insert(CGMG6FireflyTransmitter(address: dexcomG5orG6.blePeripheral.address, name: dexcomG5orG6.blePeripheral.name, transmitterID: transmitterId, bluetoothTransmitterDelegate: self, cGMG6TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, transmitterStartDate: dexcomG5orG6.transmitterStartDate, sensorStartDate: dexcomG5orG6.sensorStartDate, calibrationToSendToTransmitter: calibrationsAccessor.lastCalibrationForActiveSensor(withActivesensor: sensorsAccessor.fetchActiveSensor()), firmware: dexcomG5orG6.firmwareVersion), at: index)
}
@ -599,15 +600,16 @@ class BluetoothPeripheralManager: NSObject {
if !dexcomG5orG6.isDexcomG6 && !dexcomG5orG6.isFirefly {
newTransmitter = CGMG5Transmitter(address: dexcomG5orG6.blePeripheral.address, name: dexcomG5orG6.blePeripheral.name, transmitterID: transmitterId, bluetoothTransmitterDelegate: self, cGMG5TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, transmitterStartDate: dexcomG5orG6.transmitterStartDate, sensorStartDate: dexcomG5orG6.sensorStartDate, calibrationToSendToTransmitter: calibrationsAccessor.lastCalibrationForActiveSensor(withActivesensor: sensorsAccessor.fetchActiveSensor()), firmware: dexcomG5orG6.firmwareVersion, isFireFly: dexcomG5orG6.isFirefly)
newTransmitter = CGMG5Transmitter(address: dexcomG5orG6.blePeripheral.address, name: dexcomG5orG6.blePeripheral.name, transmitterID: transmitterId, bluetoothTransmitterDelegate: self, cGMG5TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, transmitterStartDate: dexcomG5orG6.transmitterStartDate, sensorStartDate: dexcomG5orG6.sensorStartDate, calibrationToSendToTransmitter: calibrationsAccessor.lastCalibrationForActiveSensor(withActivesensor: sensorsAccessor.fetchActiveSensor()), firmware: dexcomG5orG6.firmwareVersion)
} else if !dexcomG5orG6.isFirefly {
newTransmitter = CGMG6Transmitter(address: dexcomG5orG6.blePeripheral.address, name: dexcomG5orG6.blePeripheral.name, transmitterID: transmitterId, bluetoothTransmitterDelegate: self, cGMG6TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, transmitterStartDate: dexcomG5orG6.transmitterStartDate, sensorStartDate: dexcomG5orG6.sensorStartDate, calibrationToSendToTransmitter: calibrationsAccessor.lastCalibrationForActiveSensor(withActivesensor: sensorsAccessor.fetchActiveSensor()), firmware: dexcomG5orG6.firmwareVersion)
} else {
// CGMG6 transmitter is created for G6 or Firefly
// in the end for firefly we could as wel create it as a G5
newTransmitter = CGMG6Transmitter(address: dexcomG5orG6.blePeripheral.address, name: dexcomG5orG6.blePeripheral.name, transmitterID: transmitterId, bluetoothTransmitterDelegate: self, cGMG6TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, transmitterStartDate: dexcomG5orG6.transmitterStartDate, sensorStartDate: dexcomG5orG6.sensorStartDate, calibrationToSendToTransmitter: calibrationsAccessor.lastCalibrationForActiveSensor(withActivesensor: sensorsAccessor.fetchActiveSensor()), firmware: dexcomG5orG6.firmwareVersion, isFireFly: dexcomG5orG6.isFirefly)
newTransmitter = CGMG6FireflyTransmitter(address: dexcomG5orG6.blePeripheral.address, name: dexcomG5orG6.blePeripheral.name, transmitterID: transmitterId, bluetoothTransmitterDelegate: self, cGMG6TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, transmitterStartDate: dexcomG5orG6.transmitterStartDate, sensorStartDate: dexcomG5orG6.sensorStartDate, calibrationToSendToTransmitter: calibrationsAccessor.lastCalibrationForActiveSensor(withActivesensor: sensorsAccessor.fetchActiveSensor()), firmware: dexcomG5orG6.firmwareVersion)
}
@ -788,16 +790,21 @@ class BluetoothPeripheralManager: NSObject {
}
case .DexcomG5Type:
// every CGMG6Transmitter is CGMG5Transmitter, we need to avoid that
if bluetoothTransmitter is CGMG5Transmitter && !(bluetoothTransmitter is CGMG6Transmitter) {
// every CGMG6Transmitter and CGMG6FireflyTransmitter is CGMG5Transmitter, check that
if bluetoothTransmitter is CGMG5Transmitter && !(bluetoothTransmitter is CGMG6Transmitter) && !(bluetoothTransmitter is CGMG6FireflyTransmitter){
return .DexcomG5Type
}
case .DexcomG6Type, .DexcomG6FireflyType:
case .DexcomG6Type:
if bluetoothTransmitter is CGMG6Transmitter {
return .DexcomG6Type
}
case .DexcomG6FireflyType:
if bluetoothTransmitter is CGMG6FireflyTransmitter {
return .DexcomG6FireflyType
}
case .BubbleType:
if bluetoothTransmitter is CGMBubbleTransmitter {
return .BubbleType
@ -873,7 +880,7 @@ class BluetoothPeripheralManager: NSObject {
fatalError("in createNewTransmitter, type DexcomG5Type, transmitterId is nil or cgmTransmitterDelegate is nil")
}
return CGMG5Transmitter(address: nil, name: nil, transmitterID: transmitterId, bluetoothTransmitterDelegate: bluetoothTransmitterDelegate ?? self, cGMG5TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, transmitterStartDate: nil, sensorStartDate: nil, calibrationToSendToTransmitter: nil, firmware: nil, isFireFly: false)
return CGMG5Transmitter(address: nil, name: nil, transmitterID: transmitterId, bluetoothTransmitterDelegate: bluetoothTransmitterDelegate ?? self, cGMG5TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, transmitterStartDate: nil, sensorStartDate: nil, calibrationToSendToTransmitter: nil, firmware: nil)
case .DexcomG6Type:
@ -881,15 +888,15 @@ class BluetoothPeripheralManager: NSObject {
fatalError("in createNewTransmitter, type DexcomG6Type, transmitterId is nil or cgmTransmitterDelegate is nil")
}
return CGMG6Transmitter(address: nil, name: nil, transmitterID: transmitterId, bluetoothTransmitterDelegate: bluetoothTransmitterDelegate ?? self, cGMG6TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, transmitterStartDate: nil, sensorStartDate: nil, calibrationToSendToTransmitter: nil, firmware: nil, isFireFly: false)
return CGMG6Transmitter(address: nil, name: nil, transmitterID: transmitterId, bluetoothTransmitterDelegate: bluetoothTransmitterDelegate ?? self, cGMG6TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, transmitterStartDate: nil, sensorStartDate: nil, calibrationToSendToTransmitter: nil, firmware: nil)
case .DexcomG6FireflyType:
guard let transmitterId = transmitterId, let cgmTransmitterDelegate = cgmTransmitterDelegate else {
fatalError("in createNewTransmitter, type DexcomG6Type, transmitterId is nil or cgmTransmitterDelegate is nil")
fatalError("in createNewTransmitter, type DexcomG6FireflyType, transmitterId is nil or cgmTransmitterDelegate is nil")
}
return CGMG6Transmitter(address: nil, name: nil, transmitterID: transmitterId, bluetoothTransmitterDelegate: bluetoothTransmitterDelegate ?? self, cGMG6TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, transmitterStartDate: nil, sensorStartDate: nil, calibrationToSendToTransmitter: nil, firmware: nil, isFireFly: true)
return CGMG6FireflyTransmitter(address: nil, name: nil, transmitterID: transmitterId, bluetoothTransmitterDelegate: bluetoothTransmitterDelegate ?? self, cGMG6TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, transmitterStartDate: nil, sensorStartDate: nil, calibrationToSendToTransmitter: nil, firmware: nil)
case .BubbleType:

View File

@ -172,7 +172,6 @@ final class BluetoothPeripheralsViewController: UIViewController {
}
}

View File

@ -1845,7 +1845,6 @@ final class RootViewController: UIViewController {
// unwrap coredatamanager
guard let coreDataManager = coreDataManager else {return}
// initialize list of actions
var listOfActions = [UIAlertAction]()
@ -1854,6 +1853,7 @@ final class RootViewController: UIViewController {
let sensorStatusAction = UIAlertAction(title: Texts_HomeView.statusActionTitle, style: .default) { (UIAlertAction) in
self.showStatus()
}
listOfActions.append(sensorStatusAction)
// next action is to start or stop the sensor, can also be omitted depending on type of device - also not applicable for follower mode
@ -2720,6 +2720,17 @@ final class RootViewController: UIViewController {
/// conform to CGMTransmitterDelegate
extension RootViewController: CGMTransmitterDelegate {
func sensorStopDetected() {
trace("sensor stop detected", log: log, category: ConstantsLog.categoryRootView, type: .info)
// unwrap cgmTransmitter
guard let cgmTransmitter = self.bluetoothPeripheralManager?.getCGMTransmitter() else {return}
stopSensor(cGMTransmitter: cgmTransmitter)
}
func newSensorDetected(sensorStartDate: Date?) {
trace("new sensor detected", log: log, category: ConstantsLog.categoryRootView, type: .info)