Libre2 direct connectivity, just prepared, not tested at all
This commit is contained in:
parent
46c0aea3ec
commit
ef8f6ebbb5
|
@ -30,6 +30,13 @@
|
|||
F808D2D2240329E80084B5DB /* Bubble+BluetoothPeripheral.swift in Sources */ = {isa = PBXBuildFile; fileRef = F808D2D1240329E70084B5DB /* Bubble+BluetoothPeripheral.swift */; };
|
||||
F80D915C24F06A40006840B5 /* PreLibre2.swift in Sources */ = {isa = PBXBuildFile; fileRef = F80D915B24F06A40006840B5 /* PreLibre2.swift */; };
|
||||
F80D916024F45EB3006840B5 /* LibreError.swift in Sources */ = {isa = PBXBuildFile; fileRef = F80D915F24F45EB2006840B5 /* LibreError.swift */; };
|
||||
F80D916424F5B3DE006840B5 /* Libre2+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F80D916224F5B3DE006840B5 /* Libre2+CoreDataProperties.swift */; };
|
||||
F80D916524F5B3DE006840B5 /* Libre2+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = F80D916324F5B3DE006840B5 /* Libre2+CoreDataClass.swift */; };
|
||||
F80D916824F7086D006840B5 /* Libre2BluetoothPeripheralViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F80D916724F7086D006840B5 /* Libre2BluetoothPeripheralViewModel.swift */; };
|
||||
F80D916B24F82913006840B5 /* CGMLibre2Transmitter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F80D916A24F82913006840B5 /* CGMLibre2Transmitter.swift */; };
|
||||
F80D916D24F82A17006840B5 /* CGMLibre2TransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F80D916C24F82A17006840B5 /* CGMLibre2TransmitterDelegate.swift */; };
|
||||
F80D917024F85C7A006840B5 /* Libre2+BluetoothPeripheral.swift in Sources */ = {isa = PBXBuildFile; fileRef = F80D916F24F85C7A006840B5 /* Libre2+BluetoothPeripheral.swift */; };
|
||||
F80D917224FA9CD5006840B5 /* BluetoothPeripheralManager+CGMLibre2TransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F80D917124FA9CD5006840B5 /* BluetoothPeripheralManager+CGMLibre2TransmitterDelegate.swift */; };
|
||||
F80ED2EC236F68F90005C035 /* SettingsViewM5StackBluetoothSettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F80ED2E9236F68F90005C035 /* SettingsViewM5StackBluetoothSettingsViewModel.swift */; };
|
||||
F80ED2ED236F68F90005C035 /* SettingsViewM5StackGeneralSettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F80ED2EA236F68F90005C035 /* SettingsViewM5StackGeneralSettingsViewModel.swift */; };
|
||||
F80ED2EE236F68F90005C035 /* SettingsViewM5StackWiFiSettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F80ED2EB236F68F90005C035 /* SettingsViewM5StackWiFiSettingsViewModel.swift */; };
|
||||
|
@ -486,6 +493,14 @@
|
|||
F808D2D1240329E70084B5DB /* Bubble+BluetoothPeripheral.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bubble+BluetoothPeripheral.swift"; sourceTree = "<group>"; };
|
||||
F80D915B24F06A40006840B5 /* PreLibre2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreLibre2.swift; sourceTree = "<group>"; };
|
||||
F80D915F24F45EB2006840B5 /* LibreError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibreError.swift; sourceTree = "<group>"; };
|
||||
F80D916124F5AA62006840B5 /* xdrip v12.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "xdrip v12.xcdatamodel"; sourceTree = "<group>"; };
|
||||
F80D916224F5B3DE006840B5 /* Libre2+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Libre2+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||
F80D916324F5B3DE006840B5 /* Libre2+CoreDataClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Libre2+CoreDataClass.swift"; sourceTree = "<group>"; };
|
||||
F80D916724F7086D006840B5 /* Libre2BluetoothPeripheralViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Libre2BluetoothPeripheralViewModel.swift; sourceTree = "<group>"; };
|
||||
F80D916A24F82913006840B5 /* CGMLibre2Transmitter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGMLibre2Transmitter.swift; sourceTree = "<group>"; };
|
||||
F80D916C24F82A17006840B5 /* CGMLibre2TransmitterDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGMLibre2TransmitterDelegate.swift; sourceTree = "<group>"; };
|
||||
F80D916F24F85C7A006840B5 /* Libre2+BluetoothPeripheral.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Libre2+BluetoothPeripheral.swift"; sourceTree = "<group>"; };
|
||||
F80D917124FA9CD5006840B5 /* BluetoothPeripheralManager+CGMLibre2TransmitterDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+CGMLibre2TransmitterDelegate.swift"; sourceTree = "<group>"; };
|
||||
F80ED2E9236F68F90005C035 /* SettingsViewM5StackBluetoothSettingsViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewM5StackBluetoothSettingsViewModel.swift; sourceTree = "<group>"; };
|
||||
F80ED2EA236F68F90005C035 /* SettingsViewM5StackGeneralSettingsViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewM5StackGeneralSettingsViewModel.swift; sourceTree = "<group>"; };
|
||||
F80ED2EB236F68F90005C035 /* SettingsViewM5StackWiFiSettingsViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewM5StackWiFiSettingsViewModel.swift; sourceTree = "<group>"; };
|
||||
|
@ -1122,6 +1137,7 @@
|
|||
F808D2C3240323750084B5DB /* Libre */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F80D916624F70840006840B5 /* Libre2 */,
|
||||
F816E11F24392D27009EE65B /* Droplet */,
|
||||
F816E1112438A72C009EE65B /* BlueReader */,
|
||||
F816E10124367389009EE65B /* GNSENtry */,
|
||||
|
@ -1143,6 +1159,7 @@
|
|||
F808D2CF240329D40084B5DB /* Libre */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F80D916E24F85C5A006840B5 /* Libre2 */,
|
||||
F816E114243919ED009EE65B /* Droplet */,
|
||||
F816E1062437E58E009EE65B /* BlueReader */,
|
||||
F816E0FC24367338009EE65B /* GNSEntry */,
|
||||
|
@ -1161,6 +1178,31 @@
|
|||
path = Bubble;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F80D916624F70840006840B5 /* Libre2 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F80D916724F7086D006840B5 /* Libre2BluetoothPeripheralViewModel.swift */,
|
||||
);
|
||||
path = Libre2;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F80D916924F828D5006840B5 /* Libre2 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F80D916A24F82913006840B5 /* CGMLibre2Transmitter.swift */,
|
||||
F80D916C24F82A17006840B5 /* CGMLibre2TransmitterDelegate.swift */,
|
||||
);
|
||||
path = Libre2;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F80D916E24F85C5A006840B5 /* Libre2 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F80D916F24F85C7A006840B5 /* Libre2+BluetoothPeripheral.swift */,
|
||||
);
|
||||
path = Libre2;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F80ED2E8236F68D90005C035 /* M5StackSettingsViewModels */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -1358,6 +1400,7 @@
|
|||
F8297F44238DC4AC00D74D66 /* BluetoothPeripheralManaging.swift */,
|
||||
F816E12D2439E06E009EE65B /* BluetoothPeripheralManager+CGMDexcomG4TransmitterDelegate.swift */,
|
||||
F825286D2443C1000067AF77 /* BluetoothPeripheralManager+CGMG6TransmitterDelegate.swift */,
|
||||
F80D917124FA9CD5006840B5 /* BluetoothPeripheralManager+CGMLibre2TransmitterDelegate.swift */,
|
||||
);
|
||||
path = BluetoothPeripheral;
|
||||
sourceTree = "<group>";
|
||||
|
@ -2007,6 +2050,8 @@
|
|||
F816E11B2439243B009EE65B /* Droplet+CoreDataProperties.swift */,
|
||||
F816E0F624367137009EE65B /* GNSEntry+CoreDataClass.swift */,
|
||||
F816E0F424367131009EE65B /* GNSEntry+CoreDataProperties.swift */,
|
||||
F80D916324F5B3DE006840B5 /* Libre2+CoreDataClass.swift */,
|
||||
F80D916224F5B3DE006840B5 /* Libre2+CoreDataProperties.swift */,
|
||||
F804870A2336D90200EBDDB7 /* M5Stack+CoreDataClass.swift */,
|
||||
F804870B2336D90200EBDDB7 /* M5Stack+CoreDataProperties.swift */,
|
||||
F8C97851242AA70C00A09483 /* MiaoMiao+CoreDataClass.swift */,
|
||||
|
@ -2177,6 +2222,7 @@
|
|||
F8F971D623A5915900C3F17D /* Libre */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F80D916924F828D5006840B5 /* Libre2 */,
|
||||
F8F971D723A5915900C3F17D /* Droplet */,
|
||||
F8F971D923A5915900C3F17D /* BlueReader */,
|
||||
F8F971DB23A5915900C3F17D /* GNSEntry */,
|
||||
|
@ -2661,6 +2707,7 @@
|
|||
F8B3A84A227F090E004BA588 /* SettingsViewGeneralSettingsViewModel.swift in Sources */,
|
||||
F83098FE23AD3F84005741DF /* UITabBarController.swift in Sources */,
|
||||
F816E11A243923B2009EE65B /* Droplet+CoreDataClass.swift in Sources */,
|
||||
F80D916D24F82A17006840B5 /* CGMLibre2TransmitterDelegate.swift in Sources */,
|
||||
F816E1102437ED21009EE65B /* BluetoothPeripheralManager+CGMBlueReaderTransmitterDelegate.swift in Sources */,
|
||||
F8B3A85B2280CCD1004BA588 /* AlertSettingsViewController.swift in Sources */,
|
||||
F8F9722E23A5915900C3F17D /* M5StackTransmitterOpCode.swift in Sources */,
|
||||
|
@ -2684,6 +2731,7 @@
|
|||
F8DF765323E34F4500063910 /* DexcomG5+CoreDataClass.swift in Sources */,
|
||||
F8F9720F23A5915900C3F17D /* NSData+CRC.swift in Sources */,
|
||||
F8A1585722EDB754007F5B5D /* ConstantsCoreData.swift in Sources */,
|
||||
F80D917224FA9CD5006840B5 /* BluetoothPeripheralManager+CGMLibre2TransmitterDelegate.swift in Sources */,
|
||||
F821CF9022AB1068005C1E43 /* DatePickerViewData.swift in Sources */,
|
||||
F8F9722623A5915900C3F17D /* BluconTransmitterOpCode.swift in Sources */,
|
||||
F8025E4E21ED450300ECF0C0 /* Double.swift in Sources */,
|
||||
|
@ -2700,6 +2748,7 @@
|
|||
F8AF11FC24B27A6D00AE5BA2 /* LibreOOPWebServerResponse.swift in Sources */,
|
||||
F8F9723123A5915900C3F17D /* M5StackAuthenticateTXMessage.swift in Sources */,
|
||||
F8F9721223A5915900C3F17D /* FirmwareVersionTxMessage.swift in Sources */,
|
||||
F80D916824F7086D006840B5 /* Libre2BluetoothPeripheralViewModel.swift in Sources */,
|
||||
F867E2612252ADAB000FD265 /* Calibration+CoreDataProperties.swift in Sources */,
|
||||
F8025E6B21F7CD7600ECF0C0 /* UIStoryboard.swift in Sources */,
|
||||
F830991D23C2909E005741DF /* Watlaa+CoreDataProperties.swift in Sources */,
|
||||
|
@ -2727,6 +2776,7 @@
|
|||
F80859292364D61B00F3829D /* UserDefaults+charts.swift in Sources */,
|
||||
F8B3A7B2226A0878004BA588 /* TextsAlerts.swift in Sources */,
|
||||
F8297F46238DC4AC00D74D66 /* BluetoothPeripheralManaging.swift in Sources */,
|
||||
F80D917024F85C7A006840B5 /* Libre2+BluetoothPeripheral.swift in Sources */,
|
||||
F8F9721423A5915900C3F17D /* AuthChallengeRxMessage.swift in Sources */,
|
||||
F8025E5421EE8D2100ECF0C0 /* Libre1Calibrator.swift in Sources */,
|
||||
F81FA00A228F53680028C70F /* TextsHomeView.swift in Sources */,
|
||||
|
@ -2850,6 +2900,7 @@
|
|||
F8F9720823A5915900C3F17D /* BatteryStatusTxMessage.swift in Sources */,
|
||||
F8F9721C23A5915900C3F17D /* LibreOOPResponse.swift in Sources */,
|
||||
F81F9FFC2288C7530028C70F /* NewAlertSettingsViewController.swift in Sources */,
|
||||
F80D916524F5B3DE006840B5 /* Libre2+CoreDataClass.swift in Sources */,
|
||||
F898EDF2234A8A0500BFB79B /* UInt8.swift in Sources */,
|
||||
F8DF766423E781C100063910 /* BLEPeripheralAccessor.swift in Sources */,
|
||||
F816E12124392D40009EE65B /* DropletBluetoothPeripheralViewModel.swift in Sources */,
|
||||
|
@ -2908,7 +2959,9 @@
|
|||
F816E11E24392690009EE65B /* BluetoothPeripheralManager+CGMDropletTransmitterDelegate.swift in Sources */,
|
||||
F821CF6B229FC22D005C1E43 /* Endpoint.swift in Sources */,
|
||||
F821CF58229BF43A005C1E43 /* AlertManager.swift in Sources */,
|
||||
F80D916B24F82913006840B5 /* CGMLibre2Transmitter.swift in Sources */,
|
||||
F8297F59238EE14E00D74D66 /* TextsBluetoothPeripheralsView.swift in Sources */,
|
||||
F80D916424F5B3DE006840B5 /* Libre2+CoreDataProperties.swift in Sources */,
|
||||
F898EDEC233F549100BFB79B /* UIBarButtonItem.swift in Sources */,
|
||||
F816E0E42432A4FA009EE65B /* CGMBluconTransmitterDelegate.swift in Sources */,
|
||||
F8A389CF232AE2EA0010F405 /* M5StackSettingsViewController.swift in Sources */,
|
||||
|
@ -3402,6 +3455,7 @@
|
|||
F8AC429F21B31F160078C348 /* xdrip.xcdatamodeld */ = {
|
||||
isa = XCVersionGroup;
|
||||
children = (
|
||||
F80D916124F5AA62006840B5 /* xdrip v12.xcdatamodel */,
|
||||
F8DF765123E34E6A00063910 /* xdrip v11.xcdatamodel */,
|
||||
F8DF764E23DCF64F00063910 /* xdrip v10.xcdatamodel */,
|
||||
F830991523C28E79005741DF /* xdrip v9.xcdatamodel */,
|
||||
|
@ -3414,7 +3468,7 @@
|
|||
F85C4A93233632EC00D6A86F /* xdrip v2.xcdatamodel */,
|
||||
F8AC42A021B31F160078C348 /* xdrip.xcdatamodel */,
|
||||
);
|
||||
currentVersion = F8DF765123E34E6A00063910 /* xdrip v11.xcdatamodel */;
|
||||
currentVersion = F80D916124F5AA62006840B5 /* xdrip v12.xcdatamodel */;
|
||||
path = xdrip.xcdatamodeld;
|
||||
sourceTree = "<group>";
|
||||
versionGroupType = wrapper.xcdatamodel;
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import Foundation
|
||||
|
||||
extension Libre2: BluetoothPeripheral {
|
||||
|
||||
func bluetoothPeripheralType() -> BluetoothPeripheralType {
|
||||
return .Libre2Type
|
||||
}
|
||||
|
||||
func overrideNeedsOOPWeb() -> Bool {
|
||||
// for Libre 2 we decrypt the data, so the data will be processed as Libre 1, means user can choose to use oop web or not for defining slope parameters
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -42,6 +42,9 @@ enum BluetoothPeripheralType: String, CaseIterable {
|
|||
|
||||
/// watlaa master
|
||||
case WatlaaType = "Watlaa"
|
||||
|
||||
/// Libre 2
|
||||
case Libre2Type = "Libre2"
|
||||
|
||||
/// - returns: the BluetoothPeripheralViewModel. If nil then there's no specific settings for the tpe of bluetoothPeripheral
|
||||
func viewModel() -> BluetoothPeripheralViewModel? {
|
||||
|
@ -84,6 +87,9 @@ enum BluetoothPeripheralType: String, CaseIterable {
|
|||
case .DexcomG6Type:
|
||||
return DexcomG6BluetoothPeripheralViewModel()
|
||||
|
||||
case .Libre2Type:
|
||||
return Libre2BluetoothPeripheralViewModel()
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -149,6 +155,10 @@ enum BluetoothPeripheralType: String, CaseIterable {
|
|||
|
||||
return DexcomG4(address: address, name: name, alias: nil, nsManagedObjectContext: nsManagedObjectContext)
|
||||
|
||||
case .Libre2Type:
|
||||
|
||||
return Libre2(address: address, name: name, alias: nil, nsManagedObjectContext: nsManagedObjectContext)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -161,7 +171,7 @@ enum BluetoothPeripheralType: String, CaseIterable {
|
|||
case .M5StackType, .M5StickCType:
|
||||
return .M5Stack
|
||||
|
||||
case .DexcomG5Type, .BubbleType, .MiaoMiaoType, .BluconType, .GNSentryType, .BlueReaderType, .DropletType, .DexcomG4Type, .DexcomG6Type, .WatlaaType:
|
||||
case .DexcomG5Type, .BubbleType, .MiaoMiaoType, .BluconType, .GNSentryType, .BlueReaderType, .DropletType, .DexcomG4Type, .DexcomG6Type, .WatlaaType, .Libre2Type:
|
||||
return .CGM
|
||||
|
||||
}
|
||||
|
@ -173,7 +183,7 @@ enum BluetoothPeripheralType: String, CaseIterable {
|
|||
|
||||
switch self {
|
||||
|
||||
case .M5StackType, .M5StickCType, .WatlaaType, .BubbleType, .MiaoMiaoType, .GNSentryType, .BlueReaderType, .DropletType:
|
||||
case .M5StackType, .M5StickCType, .WatlaaType, .BubbleType, .MiaoMiaoType, .GNSentryType, .BlueReaderType, .DropletType, .Libre2Type:
|
||||
return false
|
||||
|
||||
case .DexcomG5Type, .BluconType, .DexcomG4Type, .DexcomG6Type:
|
||||
|
@ -223,7 +233,7 @@ enum BluetoothPeripheralType: String, CaseIterable {
|
|||
}
|
||||
return nil
|
||||
|
||||
case .M5StackType, .M5StickCType, .WatlaaType, .BubbleType, .MiaoMiaoType, .GNSentryType, .BlueReaderType, .DropletType:
|
||||
case .M5StackType, .M5StickCType, .WatlaaType, .BubbleType, .MiaoMiaoType, .GNSentryType, .BlueReaderType, .DropletType, .Libre2Type:
|
||||
// no transmitter id means no validation to do
|
||||
return nil
|
||||
|
||||
|
@ -253,6 +263,10 @@ enum BluetoothPeripheralType: String, CaseIterable {
|
|||
|
||||
case .BubbleType, .MiaoMiaoType:
|
||||
return true
|
||||
|
||||
case .Libre2Type:
|
||||
// oop web can still be used for Libre2 because in the end the data received is Libre 1 format, we can use oop web to get slope parameters
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
|
@ -268,7 +282,10 @@ enum BluetoothPeripheralType: String, CaseIterable {
|
|||
|
||||
case .BubbleType, .MiaoMiaoType, .WatlaaType, .BluconType, .BlueReaderType, .DropletType , .GNSentryType:
|
||||
return true
|
||||
|
||||
|
||||
case .Libre2Type:
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -73,6 +73,9 @@ enum CGMTransmitterType:String, CaseIterable {
|
|||
/// watlaa
|
||||
case watlaa = "Watlaa"
|
||||
|
||||
/// Libre2
|
||||
case Libre2 = "Libre2"
|
||||
|
||||
/// what sensorType does this CGMTransmitter type support
|
||||
func sensorType() -> CGMSensorType {
|
||||
|
||||
|
@ -81,7 +84,7 @@ enum CGMTransmitterType:String, CaseIterable {
|
|||
case .dexcomG4, .dexcomG5, .dexcomG6 :
|
||||
return .Dexcom
|
||||
|
||||
case .miaomiao, .Bubble, .GNSentry, .Droplet1, .blueReader, .watlaa, .Blucon :
|
||||
case .miaomiao, .Bubble, .GNSentry, .Droplet1, .blueReader, .watlaa, .Blucon, .Libre2:
|
||||
return .Libre
|
||||
|
||||
}
|
||||
|
@ -120,6 +123,10 @@ enum CGMTransmitterType:String, CaseIterable {
|
|||
|
||||
case .watlaa:
|
||||
return false
|
||||
|
||||
case .Libre2:
|
||||
return true
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,7 +140,7 @@ enum CGMTransmitterType:String, CaseIterable {
|
|||
case .dexcomG4, .dexcomG5, .dexcomG6, .GNSentry, .Droplet1, .blueReader, .watlaa:
|
||||
return true
|
||||
|
||||
case .miaomiao, .Bubble, .Blucon:
|
||||
case .miaomiao, .Bubble, .Blucon, .Libre2:
|
||||
return true
|
||||
|
||||
|
||||
|
@ -171,6 +178,9 @@ enum CGMTransmitterType:String, CaseIterable {
|
|||
case .watlaa:
|
||||
return ConstantsDefaultAlertLevels.defaultBatteryAlertLevelWatlaa
|
||||
|
||||
case .Libre2:
|
||||
return ConstantsDefaultAlertLevels.defaultBatteryAlertLevelLibre2
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,6 +212,9 @@ enum CGMTransmitterType:String, CaseIterable {
|
|||
case .watlaa:
|
||||
return "%"
|
||||
|
||||
case .Libre2:
|
||||
return "%"
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
import Foundation
|
||||
import os
|
||||
import CoreBluetooth
|
||||
|
||||
class CGMLibre2Transmitter:BluetoothTransmitter, CGMTransmitter {
|
||||
|
||||
// MARK: - properties
|
||||
|
||||
/// service to be discovered
|
||||
let CBUUID_Service_Libre2: String = "C97433F0-BE8F-4DC8-B6F0-5343E6100EB4"
|
||||
|
||||
/// receive characteristic
|
||||
let CBUUID_ReceiveCharacteristic_Libre2: String = "c97433f1-be8f-4dc8-b6f0-5343e6100eb4"
|
||||
|
||||
/// write characteristic
|
||||
let CBUUID_WriteCharacteristic_Libre2: String = "c97433f2-be8f-4dc8-b6f0-5343e6100eb4"
|
||||
|
||||
/// will be used to pass back bluetooth and cgm related events
|
||||
private(set) weak var cgmTransmitterDelegate: CGMTransmitterDelegate?
|
||||
|
||||
/// CGMLibre2TransmitterDelegate
|
||||
public weak var cGMLibre2TransmitterDelegate: CGMLibre2TransmitterDelegate?
|
||||
|
||||
/// is nonFixed enabled for the transmitter or not
|
||||
private var nonFixedSlopeEnabled: Bool
|
||||
|
||||
/// for trace
|
||||
private let log = OSLog(subsystem: ConstantsLog.subSystem, category: ConstantsLog.categoryCGMLibre2)
|
||||
|
||||
/// used as parameter in call to cgmTransmitterDelegate.cgmTransmitterInfoReceived, when there's no glucosedata to send
|
||||
var emptyArray: [GlucoseData] = []
|
||||
|
||||
// MARK: - Initialization
|
||||
/// - 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
|
||||
/// - bluetoothTransmitterDelegate : a bluetoothTransmitterDelegate
|
||||
/// - cGMLibre2TransmitterDelegate : a CGMLibre2TransmitterDelegate
|
||||
/// - cGMTransmitterDelegate : a CGMTransmitterDelegate
|
||||
init(address:String?, name: String?, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate, cGMLibre2TransmitterDelegate : CGMLibre2TransmitterDelegate, cGMTransmitterDelegate:CGMTransmitterDelegate, nonFixedSlopeEnabled: Bool?) {
|
||||
|
||||
// assign addressname and name or expected devicename
|
||||
var newAddressAndName:BluetoothTransmitter.DeviceAddressAndName = BluetoothTransmitter.DeviceAddressAndName.notYetConnected(expectedName: "abbott")
|
||||
if let address = address {
|
||||
newAddressAndName = BluetoothTransmitter.DeviceAddressAndName.alreadyConnectedBefore(address: address, name: name)
|
||||
}
|
||||
|
||||
// assign CGMTransmitterDelegate
|
||||
self.cgmTransmitterDelegate = cGMTransmitterDelegate
|
||||
|
||||
// assign cGMLibre2TransmitterDelegate
|
||||
self.cGMLibre2TransmitterDelegate = cGMLibre2TransmitterDelegate
|
||||
|
||||
// initialize nonFixedSlopeEnabled
|
||||
self.nonFixedSlopeEnabled = nonFixedSlopeEnabled ?? false
|
||||
|
||||
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: nil, servicesCBUUIDs: [CBUUID(string: CBUUID_Service_Libre2)], CBUUID_ReceiveCharacteristic: CBUUID_ReceiveCharacteristic_Libre2, CBUUID_WriteCharacteristic: CBUUID_WriteCharacteristic_Libre2, bluetoothTransmitterDelegate: bluetoothTransmitterDelegate)
|
||||
|
||||
}
|
||||
|
||||
// MARK: - overriden BluetoothTransmitter functions
|
||||
|
||||
override func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
|
||||
|
||||
super.peripheral(peripheral, didUpdateValueFor: characteristic, error: error)
|
||||
|
||||
trace("in peripheral didUpdateValueFor", log: log, category: ConstantsLog.categoryCGMLibre2, type: .info)
|
||||
|
||||
if let value = characteristic.value {
|
||||
|
||||
guard let valueAsString = String(bytes: value, encoding: .utf8) else {
|
||||
trace(" failed to convert value to string", log: log, category: ConstantsLog.categoryCGMLibre2, type: .error)
|
||||
return
|
||||
}
|
||||
|
||||
} else {
|
||||
trace(" value is nil, no further processing", log: log, category: ConstantsLog.categoryCGMLibre2, type: .error)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: CGMTransmitter protocol functions
|
||||
|
||||
func setNonFixedSlopeEnabled(enabled: Bool) {
|
||||
nonFixedSlopeEnabled = enabled
|
||||
}
|
||||
|
||||
/// this transmitter does not support oopWeb
|
||||
func setWebOOPEnabled(enabled: Bool) {
|
||||
}
|
||||
|
||||
func setWebOOPSite(oopWebSite: String) {}
|
||||
|
||||
func setWebOOPToken(oopWebToken: String) {}
|
||||
|
||||
func cgmTransmitterType() -> CGMTransmitterType {
|
||||
return .Libre2
|
||||
}
|
||||
|
||||
func isWebOOPEnabled() -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func isNonFixedSlopeEnabled() -> Bool {
|
||||
return nonFixedSlopeEnabled
|
||||
}
|
||||
|
||||
func requestNewReading() {
|
||||
// not supported for blucon
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
import Foundation
|
||||
|
||||
protocol CGMLibre2TransmitterDelegate: AnyObject {
|
||||
|
||||
}
|
|
@ -10,6 +10,7 @@ enum ConstantsDefaultAlertLevels {
|
|||
static let defaultBatteryAlertLevelDroplet = 20
|
||||
static let defaultBatteryAlertLevelBlueReader = 20
|
||||
static let defaultBatteryAlertLevelWatlaa = 20
|
||||
static let defaultBatteryAlertLevelLibre2 = 20
|
||||
|
||||
// blood glucose level alert values in mgdl
|
||||
static let veryHigh = 250
|
||||
|
|
|
@ -43,6 +43,9 @@ enum ConstantsLog {
|
|||
/// Blucon
|
||||
static let categoryBlucon = "Blucon "
|
||||
|
||||
/// Libre2
|
||||
static let categoryCGMLibre2 = "Libre2 "
|
||||
|
||||
/// core data manager
|
||||
static let categoryCoreDataManager = "CoreDataManager "
|
||||
|
||||
|
@ -132,5 +135,6 @@ enum ConstantsLog {
|
|||
|
||||
/// trace
|
||||
static let categoryTraceSettingsViewModel = "TraceSettingsViewModel"
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,9 @@ extension BLEPeripheral {
|
|||
// a BLEPeripheral should only have one of dexcomG5, watlaa, m5Stack, ...
|
||||
@NSManaged public var dexcomG4: DexcomG4?
|
||||
|
||||
// a BLEPeripheral should only have one of dexcomG5, watlaa, m5Stack, ...
|
||||
@NSManaged public var libre2: Libre2?
|
||||
|
||||
/// sensorSerialNumber of last sensor that was read
|
||||
@NSManaged public var sensorSerialNumber: String?
|
||||
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
import Foundation
|
||||
import CoreData
|
||||
|
||||
public class Libre2: NSManagedObject {
|
||||
|
||||
// sensorState, not stored in coreData, will only be available after having received it from the Libre2
|
||||
public var sensorState: LibreSensorState = .unknown
|
||||
|
||||
/// create Libre2
|
||||
/// - parameters:
|
||||
init(address: String, name: String, alias: String?, nsManagedObjectContext:NSManagedObjectContext) {
|
||||
|
||||
let entity = NSEntityDescription.entity(forEntityName: "Libre2", in: nsManagedObjectContext)!
|
||||
|
||||
super.init(entity: entity, insertInto: nsManagedObjectContext)
|
||||
|
||||
blePeripheral = BLEPeripheral(address: address, name: name, alias: nil, nsManagedObjectContext: nsManagedObjectContext)
|
||||
|
||||
}
|
||||
|
||||
/// create Libre2
|
||||
/// - parameters:
|
||||
init(address: String, name: String, alias: String?, timeStampLastBgReading: Date?, sensorSerialNumber: String?, webOOPEnabled: Bool, nsManagedObjectContext:NSManagedObjectContext) {
|
||||
|
||||
let entity = NSEntityDescription.entity(forEntityName: "Libre2", in: nsManagedObjectContext)!
|
||||
|
||||
super.init(entity: entity, insertInto: nsManagedObjectContext)
|
||||
|
||||
self.timeStampLastBgReading = timeStampLastBgReading
|
||||
|
||||
blePeripheral = BLEPeripheral(address: address, name: name, alias: nil, nsManagedObjectContext: nsManagedObjectContext)
|
||||
|
||||
blePeripheral.webOOPEnabled = webOOPEnabled
|
||||
|
||||
}
|
||||
|
||||
private override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?) {
|
||||
super.init(entity: entity, insertInto: context)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import Foundation
|
||||
import CoreData
|
||||
|
||||
extension Libre2 {
|
||||
|
||||
@nonobjc public class func fetchRequest() -> NSFetchRequest<Libre2> {
|
||||
return NSFetchRequest<Libre2>(entityName: "Libre2")
|
||||
}
|
||||
|
||||
// blePeripheral is required to conform to protocol BluetoothPeripheral
|
||||
@NSManaged public var blePeripheral: BLEPeripheral
|
||||
|
||||
/// timestamp of last reading read with this transmitter
|
||||
@NSManaged public var timeStampLastBgReading: Date?
|
||||
|
||||
}
|
|
@ -3,6 +3,6 @@
|
|||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>_XCCurrentVersionName</key>
|
||||
<string>xdrip v11.xcdatamodel</string>
|
||||
<string>xdrip v12.xcdatamodel</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="16119" systemVersion="19C57" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="16119" systemVersion="19G73" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<entity name="AlertEntry" representedClassName=".AlertEntry" syncable="YES">
|
||||
<attribute name="alertkind" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="start" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="16119" systemVersion="19G73" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<entity name="AlertEntry" representedClassName=".AlertEntry" syncable="YES">
|
||||
<attribute name="alertkind" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="start" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="value" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="alertType" maxCount="1" deletionRule="No Action" destinationEntity="AlertType" inverseName="alertEntries" inverseEntity="AlertType"/>
|
||||
</entity>
|
||||
<entity name="AlertType" representedClassName=".AlertType" syncable="YES">
|
||||
<attribute name="enabled" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="name" attributeType="String"/>
|
||||
<attribute name="overridemute" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="snooze" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="snoozeperiod" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="soundname" optional="YES" attributeType="String"/>
|
||||
<attribute name="vibrate" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<relationship name="alertEntries" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="AlertEntry" inverseName="alertType" inverseEntity="AlertEntry"/>
|
||||
</entity>
|
||||
<entity name="BgReading" representedClassName=".BgReading" syncable="YES">
|
||||
<attribute name="a" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="ageAdjustedRawValue" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="b" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="c" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="calculatedValue" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="calculatedValueSlope" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="calibrationFlag" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="deviceName" optional="YES" attributeType="String"/>
|
||||
<attribute name="filteredCalculatedValue" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="filteredData" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="hideSlope" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="id" attributeType="String"/>
|
||||
<attribute name="ra" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="rawData" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="rb" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="rc" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="timeStamp" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<relationship name="calibration" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Calibration" inverseName="bgreadings" inverseEntity="Calibration"/>
|
||||
<relationship name="sensor" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Sensor" inverseName="readings" inverseEntity="Sensor"/>
|
||||
</entity>
|
||||
<entity name="BLEPeripheral" representedClassName=".BLEPeripheral" syncable="YES">
|
||||
<attribute name="address" attributeType="String"/>
|
||||
<attribute name="alias" optional="YES" attributeType="String"/>
|
||||
<attribute name="lastConnectionStatusChangeTimeStamp" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="name" attributeType="String"/>
|
||||
<attribute name="nonFixedSlopeEnabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="parameterUpdateNeededAtNextConnect" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="sensorSerialNumber" optional="YES" attributeType="String"/>
|
||||
<attribute name="shouldconnect" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="transmitterId" optional="YES" attributeType="String"/>
|
||||
<attribute name="webOOPEnabled" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<relationship name="blucon" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Blucon" inverseName="blePeripheral" inverseEntity="Blucon"/>
|
||||
<relationship name="blueReader" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="BlueReader" inverseName="blePeripheral" inverseEntity="BlueReader"/>
|
||||
<relationship name="bubble" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Bubble" inverseName="blePeripheral" inverseEntity="Bubble"/>
|
||||
<relationship name="dexcomG4" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="DexcomG4" inverseName="blePeripheral" inverseEntity="DexcomG4"/>
|
||||
<relationship name="dexcomG5" optional="YES" maxCount="1" deletionRule="Deny" destinationEntity="DexcomG5" inverseName="blePeripheral" inverseEntity="DexcomG5"/>
|
||||
<relationship name="droplet" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Droplet" inverseName="blePeripheral" inverseEntity="Droplet"/>
|
||||
<relationship name="gNSEntry" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="GNSEntry" inverseName="blePeripheral" inverseEntity="GNSEntry"/>
|
||||
<relationship name="libre2" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Libre2" inverseName="blePeripheral" inverseEntity="Libre2"/>
|
||||
<relationship name="m5Stack" optional="YES" maxCount="1" deletionRule="Deny" destinationEntity="M5Stack" inverseName="blePeripheral" inverseEntity="M5Stack"/>
|
||||
<relationship name="miaoMiao" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="MiaoMiao" inverseName="blePeripheral" inverseEntity="MiaoMiao"/>
|
||||
<relationship name="watlaa" optional="YES" maxCount="1" deletionRule="Deny" destinationEntity="Watlaa" inverseName="blePeripheral" inverseEntity="Watlaa"/>
|
||||
</entity>
|
||||
<entity name="Blucon" representedClassName=".Blucon" syncable="YES">
|
||||
<attribute name="timeStampLastBgReading" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<relationship name="blePeripheral" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="BLEPeripheral" inverseName="blucon" inverseEntity="BLEPeripheral"/>
|
||||
</entity>
|
||||
<entity name="BlueReader" representedClassName=".BlueReader" syncable="YES">
|
||||
<relationship name="blePeripheral" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="BLEPeripheral" inverseName="blueReader" inverseEntity="BLEPeripheral"/>
|
||||
</entity>
|
||||
<entity name="Bubble" representedClassName=".Bubble" syncable="YES">
|
||||
<attribute name="firmware" optional="YES" attributeType="String"/>
|
||||
<attribute name="hardware" optional="YES" attributeType="String"/>
|
||||
<attribute name="timeStampLastBgReading" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<relationship name="blePeripheral" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="BLEPeripheral" inverseName="bubble" inverseEntity="BLEPeripheral"/>
|
||||
</entity>
|
||||
<entity name="Calibration" representedClassName=".Calibration" syncable="YES">
|
||||
<attribute name="adjustedRawValue" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="bg" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="deviceName" optional="YES" attributeType="String"/>
|
||||
<attribute name="distanceFromEstimate" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="estimateRawAtTimeOfCalibration" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="id" attributeType="String"/>
|
||||
<attribute name="intercept" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="possibleBad" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="rawTimeStamp" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="rawValue" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="sensorConfidence" attributeType="Double" usesScalarValueType="YES"/>
|
||||
<attribute name="slope" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="slopeConfidence" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="timeStamp" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<relationship name="bgreadings" toMany="YES" deletionRule="Deny" destinationEntity="BgReading" inverseName="calibration" inverseEntity="BgReading"/>
|
||||
<relationship name="sensor" maxCount="1" deletionRule="Nullify" destinationEntity="Sensor" inverseName="calibrations" inverseEntity="Sensor"/>
|
||||
</entity>
|
||||
<entity name="DexcomG4" representedClassName=".DexcomG4" syncable="YES">
|
||||
<relationship name="blePeripheral" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="BLEPeripheral" inverseName="dexcomG4" inverseEntity="BLEPeripheral"/>
|
||||
</entity>
|
||||
<entity name="DexcomG5" representedClassName=".DexcomG5" syncable="YES">
|
||||
<attribute name="batteryResist" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="batteryRuntime" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="batteryStatus" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="batteryTemperature" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="firmwareVersion" optional="YES" attributeType="String"/>
|
||||
<attribute name="isDexcomG6" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="lastResetTimeStamp" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="voltageA" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="voltageB" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="blePeripheral" maxCount="1" deletionRule="Cascade" destinationEntity="BLEPeripheral" inverseName="dexcomG5" inverseEntity="BLEPeripheral"/>
|
||||
</entity>
|
||||
<entity name="Droplet" representedClassName=".Droplet" syncable="YES">
|
||||
<relationship name="blePeripheral" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="BLEPeripheral" inverseName="droplet" inverseEntity="BLEPeripheral"/>
|
||||
</entity>
|
||||
<entity name="GNSEntry" representedClassName=".GNSEntry" syncable="YES">
|
||||
<attribute name="bootLoader" optional="YES" attributeType="String"/>
|
||||
<attribute name="firmwareVersion" optional="YES" attributeType="String"/>
|
||||
<attribute name="serialNumber" optional="YES" attributeType="String"/>
|
||||
<attribute name="timeStampLastBgReading" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<relationship name="blePeripheral" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="BLEPeripheral" inverseName="gNSEntry" inverseEntity="BLEPeripheral"/>
|
||||
</entity>
|
||||
<entity name="Libre2" representedClassName=".Libre2" syncable="YES">
|
||||
<attribute name="timeStampLastBgReading" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<relationship name="blePeripheral" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="BLEPeripheral" inverseName="libre2" inverseEntity="BLEPeripheral"/>
|
||||
</entity>
|
||||
<entity name="M5Stack" representedClassName=".M5Stack" syncable="YES">
|
||||
<attribute name="backGroundColor" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="blepassword" optional="YES" attributeType="String"/>
|
||||
<attribute name="brightness" optional="YES" attributeType="Integer 16" defaultValueString="100" usesScalarValueType="YES"/>
|
||||
<attribute name="connectToWiFi" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="isM5StickC" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="rotation" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="textcolor" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="blePeripheral" maxCount="1" deletionRule="Cascade" destinationEntity="BLEPeripheral" inverseName="m5Stack" inverseEntity="BLEPeripheral"/>
|
||||
</entity>
|
||||
<entity name="MiaoMiao" representedClassName=".MiaoMiao" syncable="YES">
|
||||
<attribute name="firmware" optional="YES" attributeType="String"/>
|
||||
<attribute name="hardware" optional="YES" attributeType="String"/>
|
||||
<attribute name="timeStampLastBgReading" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<relationship name="blePeripheral" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="BLEPeripheral" inverseName="miaoMiao" inverseEntity="BLEPeripheral"/>
|
||||
</entity>
|
||||
<entity name="Sensor" representedClassName=".Sensor" syncable="YES">
|
||||
<attribute name="endDate" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="id" attributeType="String"/>
|
||||
<attribute name="startDate" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="uploadedToNS" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<relationship name="calibrations" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Calibration" inverseName="sensor" inverseEntity="Calibration"/>
|
||||
<relationship name="readings" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="BgReading" inverseName="sensor" inverseEntity="BgReading"/>
|
||||
</entity>
|
||||
<entity name="Watlaa" representedClassName=".Watlaa" syncable="YES">
|
||||
<attribute name="firmware" optional="YES" attributeType="String"/>
|
||||
<attribute name="hardware" optional="YES" attributeType="String"/>
|
||||
<attribute name="timeStampLastBgReading" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<relationship name="blePeripheral" maxCount="1" deletionRule="Cascade" destinationEntity="BLEPeripheral" inverseName="watlaa" inverseEntity="BLEPeripheral"/>
|
||||
</entity>
|
||||
<elements>
|
||||
<element name="AlertEntry" positionX="-648" positionY="189" width="128" height="105"/>
|
||||
<element name="AlertType" positionX="-657" positionY="180" width="128" height="165"/>
|
||||
<element name="BgReading" positionX="-285.87109375" positionY="31.9921875" width="128" height="330"/>
|
||||
<element name="BLEPeripheral" positionX="-630" positionY="216" width="128" height="358"/>
|
||||
<element name="Blucon" positionX="-657" positionY="189" width="128" height="73"/>
|
||||
<element name="BlueReader" positionX="-639" positionY="207" width="128" height="58"/>
|
||||
<element name="Bubble" positionX="-657" positionY="189" width="128" height="103"/>
|
||||
<element name="Calibration" positionX="-859.21484375" positionY="46.21484375" width="128" height="285"/>
|
||||
<element name="DexcomG4" positionX="-621" positionY="225" width="128" height="58"/>
|
||||
<element name="DexcomG5" positionX="-648" positionY="198" width="128" height="193"/>
|
||||
<element name="Droplet" positionX="-630" positionY="216" width="128" height="58"/>
|
||||
<element name="GNSEntry" positionX="-648" positionY="198" width="128" height="118"/>
|
||||
<element name="M5Stack" positionX="-657" positionY="180" width="128" height="163"/>
|
||||
<element name="MiaoMiao" positionX="-657" positionY="189" width="128" height="103"/>
|
||||
<element name="Sensor" positionX="-603.0859375" positionY="482.2890625" width="128" height="133"/>
|
||||
<element name="Watlaa" positionX="-639" positionY="207" width="128" height="103"/>
|
||||
<element name="Libre2" positionX="-648" positionY="198" width="128" height="73"/>
|
||||
</elements>
|
||||
</model>
|
|
@ -0,0 +1,5 @@
|
|||
import Foundation
|
||||
|
||||
extension BluetoothPeripheralManager: CGMLibre2TransmitterDelegate {
|
||||
|
||||
}
|
|
@ -278,6 +278,34 @@ class BluetoothPeripheralManager: NSObject {
|
|||
|
||||
}
|
||||
|
||||
case .Libre2Type:
|
||||
|
||||
if let libre2 = blePeripheral.libre2 {
|
||||
|
||||
// add it to the list of bluetoothPeripherals
|
||||
let index = insertInBluetoothPeripherals(bluetoothPeripheral: libre2)
|
||||
|
||||
if libre2.blePeripheral.shouldconnect {
|
||||
|
||||
// create an instance of CGMDropletTransmitter, CGMDropletTransmitter will automatically try to connect to the Bubble with the address that is stored in bubble
|
||||
// add it to the array of bluetoothTransmitters
|
||||
bluetoothTransmitters.insert(CGMLibre2Transmitter(address: libre2.blePeripheral.address, name: libre2.blePeripheral.name, bluetoothTransmitterDelegate: self, cGMLibre2TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, nonFixedSlopeEnabled: libre2.blePeripheral.nonFixedSlopeEnabled), at: index)
|
||||
|
||||
// if Libre2Type is of type CGM, then assign the address to currentCgmTransmitterAddress, there shouldn't be any other bluetoothPeripherals of type .CGM with shouldconnect = true
|
||||
if bluetoothPeripheralType.category() == .CGM {
|
||||
currentCgmTransmitterAddress = blePeripheral.address
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// bluetoothTransmitters array (which shoul dhave the same number of elements as bluetoothPeripherals) needs to have an empty row for the transmitter
|
||||
bluetoothTransmitters.insert(nil, at: index)
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
case .DropletType:
|
||||
|
||||
if let droplet = blePeripheral.droplet {
|
||||
|
@ -458,7 +486,7 @@ class BluetoothPeripheralManager: NSObject {
|
|||
// no need to send reading to watlaa in master mode
|
||||
break
|
||||
|
||||
case .DexcomG5Type, .BubbleType, .MiaoMiaoType, .BluconType, .GNSentryType, .BlueReaderType, .DropletType, .DexcomG4Type, .DexcomG6Type:
|
||||
case .DexcomG5Type, .BubbleType, .MiaoMiaoType, .BluconType, .GNSentryType, .BlueReaderType, .DropletType, .DexcomG4Type, .DexcomG6Type, .Libre2Type:
|
||||
// cgm's don't receive reading, they send it
|
||||
break
|
||||
|
||||
|
@ -653,6 +681,22 @@ class BluetoothPeripheralManager: NSObject {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
case .Libre2Type:
|
||||
|
||||
if let libre2 = bluetoothPeripheral as? Libre2 {
|
||||
|
||||
if let cgmTransmitterDelegate = cgmTransmitterDelegate {
|
||||
|
||||
newTransmitter = CGMLibre2Transmitter(address: libre2.blePeripheral.address, name: libre2.blePeripheral.name, bluetoothTransmitterDelegate: self, cGMLibre2TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, nonFixedSlopeEnabled: libre2.blePeripheral.nonFixedSlopeEnabled)
|
||||
|
||||
} else {
|
||||
|
||||
trace("in getBluetoothTransmitter, case Libre2 but cgmTransmitterDelegate is nil, looks like a coding error ", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .error)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -733,6 +777,11 @@ class BluetoothPeripheralManager: NSObject {
|
|||
return .DexcomG4Type
|
||||
}
|
||||
|
||||
case .Libre2Type:
|
||||
if bluetoothTransmitter is CGMLibre2Transmitter {
|
||||
return .Libre2Type
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -828,7 +877,15 @@ class BluetoothPeripheralManager: NSObject {
|
|||
}
|
||||
|
||||
return CGMG4xDripTransmitter(address: nil, name: nil, transmitterID: transmitterId, bluetoothTransmitterDelegate: self, cGMDexcomG4TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate)
|
||||
|
||||
case .Libre2Type:
|
||||
|
||||
guard let cgmTransmitterDelegate = cgmTransmitterDelegate else {
|
||||
fatalError("in createNewTransmitter, Libre2Type, cgmTransmitterDelegate is nil")
|
||||
}
|
||||
|
||||
return CGMLibre2Transmitter(address: nil, name: nil, bluetoothTransmitterDelegate: self, cGMLibre2TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, nonFixedSlopeEnabled: nil)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1072,7 +1129,7 @@ class BluetoothPeripheralManager: NSObject {
|
|||
bluetoothPeripheral.blePeripheral.parameterUpdateNeededAtNextConnect = true
|
||||
}
|
||||
|
||||
case .WatlaaType, .DexcomG5Type, .BubbleType, .MiaoMiaoType, .BluconType, .GNSentryType, .BlueReaderType, .DropletType, .DexcomG4Type, .DexcomG6Type:
|
||||
case .WatlaaType, .DexcomG5Type, .BubbleType, .MiaoMiaoType, .BluconType, .GNSentryType, .BlueReaderType, .DropletType, .DexcomG4Type, .DexcomG6Type, .Libre2Type:
|
||||
|
||||
// oop website and oop web token need to be checked
|
||||
switch keyPathEnum {
|
||||
|
|
|
@ -441,6 +441,13 @@ class Trace {
|
|||
traceInfo.appendStringAndNewLine(" batteryLevel : " + watlaa.watlaaBatteryLevel.description)
|
||||
|
||||
}
|
||||
|
||||
case .Libre2Type:
|
||||
if let libre2 = blePeripheral.libre2 {
|
||||
|
||||
traceInfo.appendStringAndNewLine(" type = " + bluetoothPeripheralType.rawValue)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
import UIKit
|
||||
|
||||
class Libre2BluetoothPeripheralViewModel {
|
||||
|
||||
/// settings specific for Libre2
|
||||
private enum Settings: Int, CaseIterable {
|
||||
|
||||
/// battery level
|
||||
case batteryLevel = 0
|
||||
|
||||
}
|
||||
|
||||
/// Libre2 settings willb be in section 0 + numberOfGeneralSections
|
||||
private let sectionNumberForLibre2SpecificSettings = 0
|
||||
|
||||
/// reference to bluetoothPeripheralManager
|
||||
private weak var bluetoothPeripheralManager: BluetoothPeripheralManaging?
|
||||
|
||||
/// reference to the tableView
|
||||
private weak var tableView: UITableView?
|
||||
|
||||
/// reference to BluetoothPeripheralViewController that will own this Libre2BluetoothPeripheralViewModel - needed to present stuff etc
|
||||
private weak var bluetoothPeripheralViewController: BluetoothPeripheralViewController?
|
||||
|
||||
/// temporary reference to bluetoothPerpipheral, will be set in configure function.
|
||||
private var bluetoothPeripheral: BluetoothPeripheral?
|
||||
|
||||
/// it's the bluetoothPeripheral as M5Stack
|
||||
private var libre2: Libre2? {
|
||||
get {
|
||||
return bluetoothPeripheral as? Libre2
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - deinit
|
||||
|
||||
deinit {
|
||||
|
||||
// when closing the viewModel, and if there's still a bluetoothTransmitter existing, then reset the specific delegate to BluetoothPeripheralManager
|
||||
|
||||
guard let bluetoothPeripheralManager = bluetoothPeripheralManager else {return}
|
||||
|
||||
guard let libre2 = libre2 else {return}
|
||||
|
||||
guard let blueToothTransmitter = bluetoothPeripheralManager.getBluetoothTransmitter(for: libre2, createANewOneIfNecesssary: false) else {return}
|
||||
|
||||
guard let cGMLibre2BluetoothTransmitter = blueToothTransmitter as? CGMLibre2Transmitter else {return}
|
||||
|
||||
cGMLibre2BluetoothTransmitter.cGMLibre2TransmitterDelegate = bluetoothPeripheralManager as! BluetoothPeripheralManager
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - conform to BluetoothPeripheralViewModel
|
||||
|
||||
extension Libre2BluetoothPeripheralViewModel: BluetoothPeripheralViewModel {
|
||||
|
||||
func configure(bluetoothPeripheral: BluetoothPeripheral?, bluetoothPeripheralManager: BluetoothPeripheralManaging, tableView: UITableView, bluetoothPeripheralViewController: BluetoothPeripheralViewController, onLibreSensorTypeReceived: ((LibreSensorType) -> ())?) {
|
||||
|
||||
// this type of transmitter does not receive libre sensor types, so the closure onLibreSensorTypeReceived does not need to be stored
|
||||
|
||||
self.bluetoothPeripheralManager = bluetoothPeripheralManager
|
||||
|
||||
self.tableView = tableView
|
||||
|
||||
self.bluetoothPeripheralViewController = bluetoothPeripheralViewController
|
||||
|
||||
self.bluetoothPeripheral = bluetoothPeripheral
|
||||
|
||||
if let bluetoothPeripheral = bluetoothPeripheral {
|
||||
|
||||
if let droplet = bluetoothPeripheral as? Libre2 {
|
||||
|
||||
if let blueToothTransmitter = bluetoothPeripheralManager.getBluetoothTransmitter(for: droplet, createANewOneIfNecesssary: false), let cGMLibre2Transmitter = blueToothTransmitter as? CGMLibre2Transmitter {
|
||||
|
||||
// set CGMLibre2Transmitter delegate to self.
|
||||
cGMLibre2Transmitter.cGMLibre2TransmitterDelegate = self
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
fatalError("in Libre2BluetoothPeripheralViewModel, configure. bluetoothPeripheral is not Libre2")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func screenTitle() -> String {
|
||||
return BluetoothPeripheralType.Libre2Type.rawValue
|
||||
}
|
||||
|
||||
func sectionTitle(forSection section: Int) -> String {
|
||||
return BluetoothPeripheralType.Libre2Type.rawValue
|
||||
}
|
||||
|
||||
func update(cell: UITableViewCell, forRow rawValue: Int, forSection section: Int, for bluetoothPeripheral: BluetoothPeripheral) {
|
||||
|
||||
// verify that bluetoothPeripheral is a Libre2
|
||||
guard let Libre2 = bluetoothPeripheral as? Libre2 else {
|
||||
fatalError("Libre2BluetoothPeripheralViewModel update, bluetoothPeripheral is not Libre2")
|
||||
}
|
||||
|
||||
// default value for accessoryView is nil
|
||||
cell.accessoryView = nil
|
||||
|
||||
guard let setting = Settings(rawValue: rawValue) else { fatalError("Libre2BluetoothPeripheralViewModel update, unexpected setting") }
|
||||
|
||||
switch setting {
|
||||
|
||||
case .batteryLevel:
|
||||
|
||||
cell.textLabel?.text = Texts_BluetoothPeripheralsView.batteryLevel
|
||||
|
||||
// not yet supported, can we get the battery level for Libre 2 ?
|
||||
cell.detailTextLabel?.text = ""
|
||||
|
||||
cell.accessoryType = .none
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func userDidSelectRow(withSettingRawValue rawValue: Int, forSection section: Int, for bluetoothPeripheral: BluetoothPeripheral, bluetoothPeripheralManager: BluetoothPeripheralManaging) -> SettingsSelectedRowAction {
|
||||
|
||||
guard let setting = Settings(rawValue: rawValue) else { fatalError("Libre2BluetoothPeripheralViewModel userDidSelectRow, unexpected setting") }
|
||||
|
||||
switch setting {
|
||||
|
||||
case .batteryLevel:
|
||||
return .nothing
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func numberOfSettings(inSection section: Int) -> Int {
|
||||
return Settings.allCases.count
|
||||
}
|
||||
|
||||
func numberOfSections() -> Int {
|
||||
// for the moment only one specific section for DexcomG5
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// MARK: - conform to CGMDropletTransmitterDelegate
|
||||
|
||||
extension Libre2BluetoothPeripheralViewModel: CGMLibre2TransmitterDelegate {
|
||||
|
||||
}
|
||||
|
|
@ -951,7 +951,7 @@ final class RootViewController: UIViewController {
|
|||
|
||||
return DexcomCalibrator()
|
||||
|
||||
case .miaomiao, .GNSentry, .Blucon, .Bubble, .Droplet1, .blueReader, .watlaa:
|
||||
case .miaomiao, .GNSentry, .Blucon, .Bubble, .Droplet1, .blueReader, .watlaa, .Libre2:
|
||||
|
||||
if cgmTransmitter.isWebOOPEnabled() && !UserDefaults.standard.overrideWebOOPCalibration {
|
||||
|
||||
|
|
Loading…
Reference in New Issue