This commit is contained in:
Johan Degraeve 2021-02-18 22:53:21 +01:00
parent 3a981af5e5
commit f068e6df87
19 changed files with 1350 additions and 75 deletions

View File

@ -39,7 +39,6 @@
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 */; };
@ -48,29 +47,24 @@
F816E0ED2432A55F009EE65B /* BluconBluetoothPeripheralViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E0EC2432A55F009EE65B /* BluconBluetoothPeripheralViewModel.swift */; };
F816E0F02433C31B009EE65B /* Blucon+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E0EE2433C31B009EE65B /* Blucon+CoreDataProperties.swift */; };
F816E0F12433C31B009EE65B /* Blucon+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E0EF2433C31B009EE65B /* Blucon+CoreDataClass.swift */; };
F816E0F32433DAA9009EE65B /* BluetoothPeripheralManager+CGMBluconTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E0F22433DAA9009EE65B /* BluetoothPeripheralManager+CGMBluconTransmitterDelegate.swift */; };
F816E0F524367132009EE65B /* GNSEntry+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E0F424367131009EE65B /* GNSEntry+CoreDataProperties.swift */; };
F816E0F724367137009EE65B /* GNSEntry+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E0F624367137009EE65B /* GNSEntry+CoreDataClass.swift */; };
F816E0FE24367338009EE65B /* GNSEntry+BluetoothPeripheral.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E0FD24367338009EE65B /* GNSEntry+BluetoothPeripheral.swift */; };
F816E1002436734C009EE65B /* CGMGNSEntryTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E0FF2436734C009EE65B /* CGMGNSEntryTransmitterDelegate.swift */; };
F816E10324367389009EE65B /* GNSEntryBluetoothPeripheralViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E10224367389009EE65B /* GNSEntryBluetoothPeripheralViewModel.swift */; };
F816E10524368BC3009EE65B /* BluetoothPeripheralManager+CGMGNSEntryTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E10424368BC3009EE65B /* BluetoothPeripheralManager+CGMGNSEntryTransmitterDelegate.swift */; };
F816E1082437E5B9009EE65B /* BlueReader+BluetoothPeripheral.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E1072437E5B9009EE65B /* BlueReader+BluetoothPeripheral.swift */; };
F816E10A2437E7B8009EE65B /* CGMBlueReaderTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E1092437E7B8009EE65B /* CGMBlueReaderTransmitterDelegate.swift */; };
F816E10C2437EA8E009EE65B /* BlueReader+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E10B2437EA8E009EE65B /* BlueReader+CoreDataClass.swift */; };
F816E10E2437EAC9009EE65B /* BlueReader+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E10D2437EAC9009EE65B /* BlueReader+CoreDataProperties.swift */; };
F816E1102437ED21009EE65B /* BluetoothPeripheralManager+CGMBlueReaderTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E10F2437ED21009EE65B /* BluetoothPeripheralManager+CGMBlueReaderTransmitterDelegate.swift */; };
F816E11624391A02009EE65B /* Droplet+BluetoothPeripheral.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E11524391A02009EE65B /* Droplet+BluetoothPeripheral.swift */; };
F816E118243921FB009EE65B /* CGMBDropletTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E117243921FB009EE65B /* CGMBDropletTransmitterDelegate.swift */; };
F816E11A243923B2009EE65B /* Droplet+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E119243923B2009EE65B /* Droplet+CoreDataClass.swift */; };
F816E11C2439243B009EE65B /* Droplet+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E11B2439243B009EE65B /* Droplet+CoreDataProperties.swift */; };
F816E11E24392690009EE65B /* BluetoothPeripheralManager+CGMDropletTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E11D24392690009EE65B /* BluetoothPeripheralManager+CGMDropletTransmitterDelegate.swift */; };
F816E12124392D40009EE65B /* DropletBluetoothPeripheralViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E12024392D40009EE65B /* DropletBluetoothPeripheralViewModel.swift */; };
F816E1242439DB63009EE65B /* DexcomG4+BluetoothPeripheral.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E1232439DB63009EE65B /* DexcomG4+BluetoothPeripheral.swift */; };
F816E1282439DE55009EE65B /* CGMDexomG4TransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E1272439DE55009EE65B /* CGMDexomG4TransmitterDelegate.swift */; };
F816E12A2439DF3A009EE65B /* DexcomG4+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E1292439DF3A009EE65B /* DexcomG4+CoreDataClass.swift */; };
F816E12C2439DFBA009EE65B /* DexcomG4+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E12B2439DFBA009EE65B /* DexcomG4+CoreDataProperties.swift */; };
F816E12E2439E06E009EE65B /* BluetoothPeripheralManager+CGMDexcomG4TransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E12D2439E06E009EE65B /* BluetoothPeripheralManager+CGMDexcomG4TransmitterDelegate.swift */; };
F816E1312439E2DD009EE65B /* DexcomG4BluetoothPeripheralViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F816E1302439E2DD009EE65B /* DexcomG4BluetoothPeripheralViewModel.swift */; };
F8177023248CF78300AA3600 /* LibreSensorType.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8177022248CF78300AA3600 /* LibreSensorType.swift */; };
F8177025248ED4DE00AA3600 /* Libre1DerivedAlgorithmParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8177024248ED4DE00AA3600 /* Libre1DerivedAlgorithmParameters.swift */; };
@ -217,12 +211,9 @@
F8252867243E50FE0067AF77 /* ConstantsLibre.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8252866243E50FE0067AF77 /* ConstantsLibre.swift */; };
F825286A2443AE190067AF77 /* DexcomG6BluetoothPeripheralViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F82528692443AE190067AF77 /* DexcomG6BluetoothPeripheralViewModel.swift */; };
F825286C2443BEDC0067AF77 /* CGMG6TransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F825286B2443BEDC0067AF77 /* CGMG6TransmitterDelegate.swift */; };
F825286E2443C1000067AF77 /* BluetoothPeripheralManager+CGMG6TransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F825286D2443C1000067AF77 /* BluetoothPeripheralManager+CGMG6TransmitterDelegate.swift */; };
F8297F46238DC4AC00D74D66 /* BluetoothPeripheralManaging.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8297F44238DC4AC00D74D66 /* BluetoothPeripheralManaging.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 */; };
F8297F56238ED07700D74D66 /* BluetoothPeripheralManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8297F55238ED07700D74D66 /* BluetoothPeripheralManager.swift */; };
F8297F59238EE14E00D74D66 /* TextsBluetoothPeripheralsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8297F57238EE14E00D74D66 /* TextsBluetoothPeripheralsView.swift */; };
F8297F5A238EE14E00D74D66 /* TextsBluetoothPeripheralView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8297F58238EE14E00D74D66 /* TextsBluetoothPeripheralView.swift */; };
F83098FE23AD3F84005741DF /* UITabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F83098FD23AD3F84005741DF /* UITabBarController.swift */; };
@ -258,17 +249,12 @@
F870D3EA25129C43008967B0 /* Glucose+GlucoseKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = F870D3E925129C43008967B0 /* Glucose+GlucoseKit.swift */; };
F870D3EC25129FC2008967B0 /* XDripClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = F870D3EB25129FC2008967B0 /* XDripClient.swift */; };
F870D3EE2513B786008967B0 /* Trace.swift in Sources */ = {isa = PBXBuildFile; fileRef = F870D3ED2513B786008967B0 /* Trace.swift */; };
F878FA7D2405B3CF00BC6DA6 /* BluetoothPeripheralManager+CGMBubbleTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F878FA7C2405B3CF00BC6DA6 /* BluetoothPeripheralManager+CGMBubbleTransmitterDelegate.swift */; };
F8797CEA255B43960033956B /* GlucoseData+Smoothable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8797CE9255B43960033956B /* GlucoseData+Smoothable.swift */; };
F889CB6F236D84AC00A81068 /* M5StackView.strings in Resources */ = {isa = PBXBuildFile; fileRef = F889CB71236D84AC00A81068 /* M5StackView.strings */; };
F890E07A247687AE008FB2EC /* URL.swift in Sources */ = {isa = PBXBuildFile; fileRef = F890E079247687AE008FB2EC /* URL.swift */; };
F897AAF92200F2D200CDDD10 /* CBPeripheralState.swift in Sources */ = {isa = PBXBuildFile; fileRef = F897AAF82200F2D200CDDD10 /* CBPeripheralState.swift */; };
F897AAFB2201018800CDDD10 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = F897AAFA2201018800CDDD10 /* String.swift */; };
F897E24B23FC86CF0075E0E8 /* CGMG5TransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F897E24A23FC86CF0075E0E8 /* CGMG5TransmitterDelegate.swift */; };
F897E25023FC871C0075E0E8 /* BluetoothPeripheralManager+CGMG5TransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F897E24C23FC871C0075E0E8 /* BluetoothPeripheralManager+CGMG5TransmitterDelegate.swift */; };
F897E25123FC871C0075E0E8 /* BluetoothPeripheralManager+M5StackBluetoothTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F897E24D23FC871C0075E0E8 /* BluetoothPeripheralManager+M5StackBluetoothTransmitterDelegate.swift */; };
F897E25223FC871C0075E0E8 /* BluetoothPeripheralManager+BluetoothTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F897E24E23FC871C0075E0E8 /* BluetoothPeripheralManager+BluetoothTransmitterDelegate.swift */; };
F897E25323FC871C0075E0E8 /* BluetoothPeripheralManager+WatlaaBluetoothTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F897E24F23FC871C0075E0E8 /* BluetoothPeripheralManager+WatlaaBluetoothTransmitterDelegate.swift */; };
F898EDEA233F53BF00BFB79B /* UIButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F898EDE9233F53BF00BFB79B /* UIButton.swift */; };
F898EDEC233F549100BFB79B /* UIBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F898EDEB233F549100BFB79B /* UIBarButtonItem.swift */; };
F898EDF2234A8A0500BFB79B /* UInt8.swift in Sources */ = {isa = PBXBuildFile; fileRef = F898EDF1234A8A0500BFB79B /* UInt8.swift */; };
@ -293,6 +279,29 @@
F8A1587122EDC865007F5B5D /* ConstantsSpeakReadingLanguages.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A1587022EDC865007F5B5D /* ConstantsSpeakReadingLanguages.swift */; };
F8A1587322EDC893007F5B5D /* ConstantsDexcomShare.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A1587222EDC893007F5B5D /* ConstantsDexcomShare.swift */; };
F8A1850C25643B16000EF8A0 /* Double+Smoothable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A1850B25643B16000EF8A0 /* Double+Smoothable.swift */; };
F8A2BBFD25D9D386001D1E78 /* AtomBluetoothPeripheralViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BBFC25D9D386001D1E78 /* AtomBluetoothPeripheralViewModel.swift */; };
F8A2BC0425DB093B001D1E78 /* Atom+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC0325DB093B001D1E78 /* Atom+CoreDataClass.swift */; };
F8A2BC0825DB09BE001D1E78 /* Atom+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC0725DB09BE001D1E78 /* Atom+CoreDataProperties.swift */; };
F8A2BC0D25DB0B12001D1E78 /* Atom+BluetoothPeripheral.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC0C25DB0B12001D1E78 /* Atom+BluetoothPeripheral.swift */; };
F8A2BC1425DB0B61001D1E78 /* CGMAtomTransmitter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC1325DB0B61001D1E78 /* CGMAtomTransmitter.swift */; };
F8A2BC1A25DB0C28001D1E78 /* CGMAtomTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC1925DB0C28001D1E78 /* CGMAtomTransmitterDelegate.swift */; };
F8A2BC2D25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMG5TransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC1E25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMG5TransmitterDelegate.swift */; };
F8A2BC2E25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMDropletTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC1F25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMDropletTransmitterDelegate.swift */; };
F8A2BC2F25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMBlueReaderTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC2025DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMBlueReaderTransmitterDelegate.swift */; };
F8A2BC3025DB0D6D001D1E78 /* BluetoothPeripheralManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC2125DB0D6D001D1E78 /* BluetoothPeripheralManager.swift */; };
F8A2BC3125DB0D6D001D1E78 /* BluetoothPeripheralManager+M5StackBluetoothTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC2225DB0D6D001D1E78 /* BluetoothPeripheralManager+M5StackBluetoothTransmitterDelegate.swift */; };
F8A2BC3225DB0D6D001D1E78 /* BluetoothPeripheralManaging.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC2325DB0D6D001D1E78 /* BluetoothPeripheralManaging.swift */; };
F8A2BC3325DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMDexcomG4TransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC2425DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMDexcomG4TransmitterDelegate.swift */; };
F8A2BC3425DB0D6D001D1E78 /* BluetoothPeripheralManager+WatlaaBluetoothTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC2525DB0D6D001D1E78 /* BluetoothPeripheralManager+WatlaaBluetoothTransmitterDelegate.swift */; };
F8A2BC3525DB0D6D001D1E78 /* BluetoothPeripheralManager+BluetoothTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC2625DB0D6D001D1E78 /* BluetoothPeripheralManager+BluetoothTransmitterDelegate.swift */; };
F8A2BC3625DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMG6TransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC2725DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMG6TransmitterDelegate.swift */; };
F8A2BC3725DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMMiaoMiaoTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC2825DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMMiaoMiaoTransmitterDelegate.swift */; };
F8A2BC3825DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMBluconTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC2925DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMBluconTransmitterDelegate.swift */; };
F8A2BC3925DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMLibre2TransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC2A25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMLibre2TransmitterDelegate.swift */; };
F8A2BC3A25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMGNSEntryTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC2B25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMGNSEntryTransmitterDelegate.swift */; };
F8A2BC3B25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMBubbleTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC2C25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMBubbleTransmitterDelegate.swift */; };
F8A2BC3F25DB0D89001D1E78 /* BluetoothPeripheralManager+CGMAtomTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC3E25DB0D89001D1E78 /* BluetoothPeripheralManager+CGMAtomTransmitterDelegate.swift */; };
F8A2BC4525DB2679001D1E78 /* AtomResponseType.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A2BC4425DB2679001D1E78 /* AtomResponseType.swift */; };
F8A389C823203E3E0010F405 /* ConstantsM5Stack.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A389C723203E3E0010F405 /* ConstantsM5Stack.swift */; };
F8A389CF232AE2EA0010F405 /* M5StackSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A389CE232AE2E90010F405 /* M5StackSettingsViewController.swift */; };
F8A389E7232ECE7E0010F405 /* SettingsViewUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A389E6232ECE7E0010F405 /* SettingsViewUtilities.swift */; };
@ -392,7 +401,6 @@
F8C97854242AA70D00A09483 /* MiaoMiao+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8C97852242AA70C00A09483 /* MiaoMiao+CoreDataProperties.swift */; };
F8C97856242AA86B00A09483 /* CGMMiaoMiaoTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8C97855242AA86B00A09483 /* CGMMiaoMiaoTransmitterDelegate.swift */; };
F8C97859242AAE7B00A09483 /* MiaoMiao+BluetoothPeripheral.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8C97858242AAE7A00A09483 /* MiaoMiao+BluetoothPeripheral.swift */; };
F8C9785B242ABD9800A09483 /* BluetoothPeripheralManager+CGMMiaoMiaoTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8C9785A242ABD9800A09483 /* BluetoothPeripheralManager+CGMMiaoMiaoTransmitterDelegate.swift */; };
F8D0587C24BCB570008C8734 /* SettingsViewHomeScreenSettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8D0587B24BCB570008C8734 /* SettingsViewHomeScreenSettingsViewModel.swift */; };
F8DF765323E34F4500063910 /* DexcomG5+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8DF765223E34F4500063910 /* DexcomG5+CoreDataClass.swift */; };
F8DF765523E34FD500063910 /* DexcomG5+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8DF765423E34FD500063910 /* DexcomG5+CoreDataProperties.swift */; };
@ -586,7 +594,6 @@
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>"; };
@ -595,29 +602,24 @@
F816E0EC2432A55F009EE65B /* BluconBluetoothPeripheralViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BluconBluetoothPeripheralViewModel.swift; sourceTree = "<group>"; };
F816E0EE2433C31B009EE65B /* Blucon+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Blucon+CoreDataProperties.swift"; sourceTree = "<group>"; };
F816E0EF2433C31B009EE65B /* Blucon+CoreDataClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Blucon+CoreDataClass.swift"; sourceTree = "<group>"; };
F816E0F22433DAA9009EE65B /* BluetoothPeripheralManager+CGMBluconTransmitterDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+CGMBluconTransmitterDelegate.swift"; sourceTree = "<group>"; };
F816E0F424367131009EE65B /* GNSEntry+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GNSEntry+CoreDataProperties.swift"; sourceTree = "<group>"; };
F816E0F624367137009EE65B /* GNSEntry+CoreDataClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GNSEntry+CoreDataClass.swift"; sourceTree = "<group>"; };
F816E0FD24367338009EE65B /* GNSEntry+BluetoothPeripheral.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GNSEntry+BluetoothPeripheral.swift"; sourceTree = "<group>"; };
F816E0FF2436734C009EE65B /* CGMGNSEntryTransmitterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGMGNSEntryTransmitterDelegate.swift; sourceTree = "<group>"; };
F816E10224367389009EE65B /* GNSEntryBluetoothPeripheralViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GNSEntryBluetoothPeripheralViewModel.swift; sourceTree = "<group>"; };
F816E10424368BC3009EE65B /* BluetoothPeripheralManager+CGMGNSEntryTransmitterDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+CGMGNSEntryTransmitterDelegate.swift"; sourceTree = "<group>"; };
F816E1072437E5B9009EE65B /* BlueReader+BluetoothPeripheral.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BlueReader+BluetoothPeripheral.swift"; sourceTree = "<group>"; };
F816E1092437E7B8009EE65B /* CGMBlueReaderTransmitterDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGMBlueReaderTransmitterDelegate.swift; sourceTree = "<group>"; };
F816E10B2437EA8E009EE65B /* BlueReader+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BlueReader+CoreDataClass.swift"; sourceTree = "<group>"; };
F816E10D2437EAC9009EE65B /* BlueReader+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BlueReader+CoreDataProperties.swift"; sourceTree = "<group>"; };
F816E10F2437ED21009EE65B /* BluetoothPeripheralManager+CGMBlueReaderTransmitterDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+CGMBlueReaderTransmitterDelegate.swift"; sourceTree = "<group>"; };
F816E11524391A02009EE65B /* Droplet+BluetoothPeripheral.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Droplet+BluetoothPeripheral.swift"; sourceTree = "<group>"; };
F816E117243921FB009EE65B /* CGMBDropletTransmitterDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGMBDropletTransmitterDelegate.swift; sourceTree = "<group>"; };
F816E119243923B2009EE65B /* Droplet+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Droplet+CoreDataClass.swift"; sourceTree = "<group>"; };
F816E11B2439243B009EE65B /* Droplet+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Droplet+CoreDataProperties.swift"; sourceTree = "<group>"; };
F816E11D24392690009EE65B /* BluetoothPeripheralManager+CGMDropletTransmitterDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+CGMDropletTransmitterDelegate.swift"; sourceTree = "<group>"; };
F816E12024392D40009EE65B /* DropletBluetoothPeripheralViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropletBluetoothPeripheralViewModel.swift; sourceTree = "<group>"; };
F816E1232439DB63009EE65B /* DexcomG4+BluetoothPeripheral.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DexcomG4+BluetoothPeripheral.swift"; sourceTree = "<group>"; };
F816E1272439DE55009EE65B /* CGMDexomG4TransmitterDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGMDexomG4TransmitterDelegate.swift; sourceTree = "<group>"; };
F816E1292439DF3A009EE65B /* DexcomG4+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DexcomG4+CoreDataClass.swift"; sourceTree = "<group>"; };
F816E12B2439DFBA009EE65B /* DexcomG4+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DexcomG4+CoreDataProperties.swift"; sourceTree = "<group>"; };
F816E12D2439E06E009EE65B /* BluetoothPeripheralManager+CGMDexcomG4TransmitterDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+CGMDexcomG4TransmitterDelegate.swift"; sourceTree = "<group>"; };
F816E1302439E2DD009EE65B /* DexcomG4BluetoothPeripheralViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexcomG4BluetoothPeripheralViewModel.swift; sourceTree = "<group>"; };
F8177022248CF78300AA3600 /* LibreSensorType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibreSensorType.swift; sourceTree = "<group>"; };
F8177024248ED4DE00AA3600 /* Libre1DerivedAlgorithmParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Libre1DerivedAlgorithmParameters.swift; sourceTree = "<group>"; };
@ -917,12 +919,9 @@
F8252866243E50FE0067AF77 /* ConstantsLibre.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstantsLibre.swift; sourceTree = "<group>"; };
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>"; };
F825286D2443C1000067AF77 /* BluetoothPeripheralManager+CGMG6TransmitterDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+CGMG6TransmitterDelegate.swift"; sourceTree = "<group>"; };
F8297F44238DC4AC00D74D66 /* BluetoothPeripheralManaging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BluetoothPeripheralManaging.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>"; };
F8297F55238ED07700D74D66 /* BluetoothPeripheralManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BluetoothPeripheralManager.swift; sourceTree = "<group>"; };
F8297F57238EE14E00D74D66 /* TextsBluetoothPeripheralsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextsBluetoothPeripheralsView.swift; sourceTree = "<group>"; };
F8297F58238EE14E00D74D66 /* TextsBluetoothPeripheralView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextsBluetoothPeripheralView.swift; sourceTree = "<group>"; };
F83098FD23AD3F84005741DF /* UITabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITabBarController.swift; sourceTree = "<group>"; };
@ -979,7 +978,6 @@
F870D3E925129C43008967B0 /* Glucose+GlucoseKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Glucose+GlucoseKit.swift"; sourceTree = "<group>"; };
F870D3EB25129FC2008967B0 /* XDripClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XDripClient.swift; sourceTree = "<group>"; };
F870D3ED2513B786008967B0 /* Trace.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Trace.swift; sourceTree = "<group>"; };
F878FA7C2405B3CF00BC6DA6 /* BluetoothPeripheralManager+CGMBubbleTransmitterDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+CGMBubbleTransmitterDelegate.swift"; sourceTree = "<group>"; };
F8797CE9255B43960033956B /* GlucoseData+Smoothable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GlucoseData+Smoothable.swift"; sourceTree = "<group>"; };
F87F5EFD2560686C00FFA395 /* xdrip v15.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "xdrip v15.xcdatamodel"; sourceTree = "<group>"; };
F889CB70236D84AC00A81068 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/M5StackView.strings; sourceTree = "<group>"; };
@ -990,10 +988,6 @@
F897AAF82200F2D200CDDD10 /* CBPeripheralState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CBPeripheralState.swift; sourceTree = "<group>"; };
F897AAFA2201018800CDDD10 /* String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = "<group>"; };
F897E24A23FC86CF0075E0E8 /* CGMG5TransmitterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGMG5TransmitterDelegate.swift; sourceTree = "<group>"; };
F897E24C23FC871C0075E0E8 /* BluetoothPeripheralManager+CGMG5TransmitterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+CGMG5TransmitterDelegate.swift"; sourceTree = "<group>"; };
F897E24D23FC871C0075E0E8 /* BluetoothPeripheralManager+M5StackBluetoothTransmitterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+M5StackBluetoothTransmitterDelegate.swift"; sourceTree = "<group>"; };
F897E24E23FC871C0075E0E8 /* BluetoothPeripheralManager+BluetoothTransmitterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+BluetoothTransmitterDelegate.swift"; sourceTree = "<group>"; };
F897E24F23FC871C0075E0E8 /* BluetoothPeripheralManager+WatlaaBluetoothTransmitterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+WatlaaBluetoothTransmitterDelegate.swift"; sourceTree = "<group>"; };
F898EDE9233F53BF00BFB79B /* UIButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIButton.swift; sourceTree = "<group>"; };
F898EDEB233F549100BFB79B /* UIBarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIBarButtonItem.swift; sourceTree = "<group>"; };
F898EDF1234A8A0500BFB79B /* UInt8.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UInt8.swift; sourceTree = "<group>"; };
@ -1018,6 +1012,30 @@
F8A1587022EDC865007F5B5D /* ConstantsSpeakReadingLanguages.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConstantsSpeakReadingLanguages.swift; sourceTree = "<group>"; };
F8A1587222EDC893007F5B5D /* ConstantsDexcomShare.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConstantsDexcomShare.swift; sourceTree = "<group>"; };
F8A1850B25643B16000EF8A0 /* Double+Smoothable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Double+Smoothable.swift"; sourceTree = "<group>"; };
F8A2BBFC25D9D386001D1E78 /* AtomBluetoothPeripheralViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomBluetoothPeripheralViewModel.swift; sourceTree = "<group>"; };
F8A2BC0225D9D471001D1E78 /* xdrip v16.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "xdrip v16.xcdatamodel"; sourceTree = "<group>"; };
F8A2BC0325DB093B001D1E78 /* Atom+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Atom+CoreDataClass.swift"; sourceTree = "<group>"; };
F8A2BC0725DB09BE001D1E78 /* Atom+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Atom+CoreDataProperties.swift"; sourceTree = "<group>"; };
F8A2BC0C25DB0B12001D1E78 /* Atom+BluetoothPeripheral.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Atom+BluetoothPeripheral.swift"; sourceTree = "<group>"; };
F8A2BC1325DB0B61001D1E78 /* CGMAtomTransmitter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGMAtomTransmitter.swift; sourceTree = "<group>"; };
F8A2BC1925DB0C28001D1E78 /* CGMAtomTransmitterDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGMAtomTransmitterDelegate.swift; sourceTree = "<group>"; };
F8A2BC1E25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMG5TransmitterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+CGMG5TransmitterDelegate.swift"; sourceTree = "<group>"; };
F8A2BC1F25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMDropletTransmitterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+CGMDropletTransmitterDelegate.swift"; sourceTree = "<group>"; };
F8A2BC2025DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMBlueReaderTransmitterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+CGMBlueReaderTransmitterDelegate.swift"; sourceTree = "<group>"; };
F8A2BC2125DB0D6D001D1E78 /* BluetoothPeripheralManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BluetoothPeripheralManager.swift; sourceTree = "<group>"; };
F8A2BC2225DB0D6D001D1E78 /* BluetoothPeripheralManager+M5StackBluetoothTransmitterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+M5StackBluetoothTransmitterDelegate.swift"; sourceTree = "<group>"; };
F8A2BC2325DB0D6D001D1E78 /* BluetoothPeripheralManaging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BluetoothPeripheralManaging.swift; sourceTree = "<group>"; };
F8A2BC2425DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMDexcomG4TransmitterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+CGMDexcomG4TransmitterDelegate.swift"; sourceTree = "<group>"; };
F8A2BC2525DB0D6D001D1E78 /* BluetoothPeripheralManager+WatlaaBluetoothTransmitterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+WatlaaBluetoothTransmitterDelegate.swift"; sourceTree = "<group>"; };
F8A2BC2625DB0D6D001D1E78 /* BluetoothPeripheralManager+BluetoothTransmitterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+BluetoothTransmitterDelegate.swift"; sourceTree = "<group>"; };
F8A2BC2725DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMG6TransmitterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+CGMG6TransmitterDelegate.swift"; sourceTree = "<group>"; };
F8A2BC2825DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMMiaoMiaoTransmitterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+CGMMiaoMiaoTransmitterDelegate.swift"; sourceTree = "<group>"; };
F8A2BC2925DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMBluconTransmitterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+CGMBluconTransmitterDelegate.swift"; sourceTree = "<group>"; };
F8A2BC2A25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMLibre2TransmitterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+CGMLibre2TransmitterDelegate.swift"; sourceTree = "<group>"; };
F8A2BC2B25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMGNSEntryTransmitterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+CGMGNSEntryTransmitterDelegate.swift"; sourceTree = "<group>"; };
F8A2BC2C25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMBubbleTransmitterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+CGMBubbleTransmitterDelegate.swift"; sourceTree = "<group>"; };
F8A2BC3E25DB0D89001D1E78 /* BluetoothPeripheralManager+CGMAtomTransmitterDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+CGMAtomTransmitterDelegate.swift"; sourceTree = "<group>"; };
F8A2BC4425DB2679001D1E78 /* AtomResponseType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomResponseType.swift; sourceTree = "<group>"; };
F8A389C723203E3E0010F405 /* ConstantsM5Stack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConstantsM5Stack.swift; sourceTree = "<group>"; };
F8A389CE232AE2E90010F405 /* M5StackSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = M5StackSettingsViewController.swift; sourceTree = "<group>"; };
F8A389E6232ECE7E0010F405 /* SettingsViewUtilities.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewUtilities.swift; sourceTree = "<group>"; };
@ -1162,7 +1180,6 @@
F8C97852242AA70C00A09483 /* MiaoMiao+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MiaoMiao+CoreDataProperties.swift"; sourceTree = "<group>"; };
F8C97855242AA86B00A09483 /* CGMMiaoMiaoTransmitterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGMMiaoMiaoTransmitterDelegate.swift; sourceTree = "<group>"; };
F8C97858242AAE7A00A09483 /* MiaoMiao+BluetoothPeripheral.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MiaoMiao+BluetoothPeripheral.swift"; sourceTree = "<group>"; };
F8C9785A242ABD9800A09483 /* BluetoothPeripheralManager+CGMMiaoMiaoTransmitterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BluetoothPeripheralManager+CGMMiaoMiaoTransmitterDelegate.swift"; sourceTree = "<group>"; };
F8D0587B24BCB570008C8734 /* SettingsViewHomeScreenSettingsViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewHomeScreenSettingsViewModel.swift; sourceTree = "<group>"; };
F8DF765223E34F4500063910 /* DexcomG5+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DexcomG5+CoreDataClass.swift"; sourceTree = "<group>"; };
F8DF765423E34FD500063910 /* DexcomG5+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DexcomG5+CoreDataProperties.swift"; sourceTree = "<group>"; };
@ -1381,6 +1398,7 @@
F808D2C3240323750084B5DB /* Libre */ = {
isa = PBXGroup;
children = (
F8A2BBFB25D9D36C001D1E78 /* Atom */,
F80D916624F70840006840B5 /* Libre2 */,
F816E11F24392D27009EE65B /* Droplet */,
F816E10124367389009EE65B /* GNSENtry */,
@ -1402,6 +1420,7 @@
F808D2CF240329D40084B5DB /* Libre */ = {
isa = PBXGroup;
children = (
F8A2BC0B25DB0AF9001D1E78 /* Atom */,
F80D916E24F85C5A006840B5 /* Libre2 */,
F816E114243919ED009EE65B /* Droplet */,
F816E1062437E58E009EE65B /* BlueReader */,
@ -1623,21 +1642,7 @@
F8297F42238DC4AC00D74D66 /* BluetoothPeripheral */ = {
isa = PBXGroup;
children = (
F8297F55238ED07700D74D66 /* BluetoothPeripheralManager.swift */,
F897E24E23FC871C0075E0E8 /* BluetoothPeripheralManager+BluetoothTransmitterDelegate.swift */,
F816E0F22433DAA9009EE65B /* BluetoothPeripheralManager+CGMBluconTransmitterDelegate.swift */,
F816E10F2437ED21009EE65B /* BluetoothPeripheralManager+CGMBlueReaderTransmitterDelegate.swift */,
F878FA7C2405B3CF00BC6DA6 /* BluetoothPeripheralManager+CGMBubbleTransmitterDelegate.swift */,
F816E12D2439E06E009EE65B /* BluetoothPeripheralManager+CGMDexcomG4TransmitterDelegate.swift */,
F816E11D24392690009EE65B /* BluetoothPeripheralManager+CGMDropletTransmitterDelegate.swift */,
F897E24C23FC871C0075E0E8 /* BluetoothPeripheralManager+CGMG5TransmitterDelegate.swift */,
F825286D2443C1000067AF77 /* BluetoothPeripheralManager+CGMG6TransmitterDelegate.swift */,
F816E10424368BC3009EE65B /* BluetoothPeripheralManager+CGMGNSEntryTransmitterDelegate.swift */,
F80D917124FA9CD5006840B5 /* BluetoothPeripheralManager+CGMLibre2TransmitterDelegate.swift */,
F8C9785A242ABD9800A09483 /* BluetoothPeripheralManager+CGMMiaoMiaoTransmitterDelegate.swift */,
F897E24D23FC871C0075E0E8 /* BluetoothPeripheralManager+M5StackBluetoothTransmitterDelegate.swift */,
F897E24F23FC871C0075E0E8 /* BluetoothPeripheralManager+WatlaaBluetoothTransmitterDelegate.swift */,
F8297F44238DC4AC00D74D66 /* BluetoothPeripheralManaging.swift */,
F8A2BC1D25DB0D6D001D1E78 /* BluetoothPeripheral */,
);
path = BluetoothPeripheral;
sourceTree = "<group>";
@ -1814,6 +1819,55 @@
path = Texts;
sourceTree = "<group>";
};
F8A2BBFB25D9D36C001D1E78 /* Atom */ = {
isa = PBXGroup;
children = (
F8A2BBFC25D9D386001D1E78 /* AtomBluetoothPeripheralViewModel.swift */,
);
path = Atom;
sourceTree = "<group>";
};
F8A2BC0B25DB0AF9001D1E78 /* Atom */ = {
isa = PBXGroup;
children = (
F8A2BC0C25DB0B12001D1E78 /* Atom+BluetoothPeripheral.swift */,
);
path = Atom;
sourceTree = "<group>";
};
F8A2BC1225DB0B4F001D1E78 /* Atom */ = {
isa = PBXGroup;
children = (
F8A2BC1325DB0B61001D1E78 /* CGMAtomTransmitter.swift */,
F8A2BC1925DB0C28001D1E78 /* CGMAtomTransmitterDelegate.swift */,
F8A2BC4425DB2679001D1E78 /* AtomResponseType.swift */,
);
path = Atom;
sourceTree = "<group>";
};
F8A2BC1D25DB0D6D001D1E78 /* BluetoothPeripheral */ = {
isa = PBXGroup;
children = (
F8A2BC1E25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMG5TransmitterDelegate.swift */,
F8A2BC1F25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMDropletTransmitterDelegate.swift */,
F8A2BC2025DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMBlueReaderTransmitterDelegate.swift */,
F8A2BC2125DB0D6D001D1E78 /* BluetoothPeripheralManager.swift */,
F8A2BC2225DB0D6D001D1E78 /* BluetoothPeripheralManager+M5StackBluetoothTransmitterDelegate.swift */,
F8A2BC2325DB0D6D001D1E78 /* BluetoothPeripheralManaging.swift */,
F8A2BC2425DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMDexcomG4TransmitterDelegate.swift */,
F8A2BC2525DB0D6D001D1E78 /* BluetoothPeripheralManager+WatlaaBluetoothTransmitterDelegate.swift */,
F8A2BC2625DB0D6D001D1E78 /* BluetoothPeripheralManager+BluetoothTransmitterDelegate.swift */,
F8A2BC2725DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMG6TransmitterDelegate.swift */,
F8A2BC2825DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMMiaoMiaoTransmitterDelegate.swift */,
F8A2BC2925DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMBluconTransmitterDelegate.swift */,
F8A2BC2A25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMLibre2TransmitterDelegate.swift */,
F8A2BC2B25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMGNSEntryTransmitterDelegate.swift */,
F8A2BC2C25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMBubbleTransmitterDelegate.swift */,
F8A2BC3E25DB0D89001D1E78 /* BluetoothPeripheralManager+CGMAtomTransmitterDelegate.swift */,
);
name = BluetoothPeripheral;
sourceTree = "<group>";
};
F8A389CD232A6A6F0010F405 /* M5StackSettingsViewController */ = {
isa = PBXGroup;
children = (
@ -2326,6 +2380,8 @@
F8B3A79222635A25004BA588 /* AlertEntry+CoreDataProperties.swift */,
F8B3A78C22622953004BA588 /* AlertType+CoreDataClass.swift */,
F8B3A79022635A25004BA588 /* AlertType+CoreDataProperties.swift */,
F8A2BC0325DB093B001D1E78 /* Atom+CoreDataClass.swift */,
F8A2BC0725DB09BE001D1E78 /* Atom+CoreDataProperties.swift */,
F85DC2F221CFE3D400B9F74A /* BgReading+CoreDataClass.swift */,
F85DC2E721CFE2F500B9F74A /* BgReading+CoreDataProperties.swift */,
F8DF765F23E38FC100063910 /* BLEPeripheral+CoreDataClass.swift */,
@ -2534,6 +2590,7 @@
F8F971D623A5915900C3F17D /* Libre */ = {
isa = PBXGroup;
children = (
F8A2BC1225DB0B4F001D1E78 /* Atom */,
F80D916924F828D5006840B5 /* Libre2 */,
F8F971D723A5915900C3F17D /* Droplet */,
F8F971D923A5915900C3F17D /* BlueReader */,
@ -3051,7 +3108,6 @@
F83098FE23AD3F84005741DF /* UITabBarController.swift in Sources */,
F816E11A243923B2009EE65B /* Droplet+CoreDataClass.swift in Sources */,
F80D916D24F82A17006840B5 /* CGMLibre2TransmitterDelegate.swift in Sources */,
F816E1102437ED21009EE65B /* BluetoothPeripheralManager+CGMBlueReaderTransmitterDelegate.swift in Sources */,
F8B955EB2591355200C06016 /* CGMLibre2Transmitter+TestData.swift in Sources */,
F8B3A85B2280CCD1004BA588 /* AlertSettingsViewController.swift in Sources */,
F8F9722E23A5915900C3F17D /* M5StackTransmitterOpCode.swift in Sources */,
@ -3064,20 +3120,19 @@
F8F9721E23A5915900C3F17D /* LibreSensorState.swift in Sources */,
F8B3A85D22821BB6004BA588 /* Int.swift in Sources */,
F808D2CE2403292C0084B5DB /* Bubble+CoreDataProperties.swift in Sources */,
F8A2BC1A25DB0C28001D1E78 /* CGMAtomTransmitterDelegate.swift in Sources */,
F816E1002436734C009EE65B /* CGMGNSEntryTransmitterDelegate.swift in Sources */,
F8C97853242AA70D00A09483 /* MiaoMiao+CoreDataClass.swift in Sources */,
F8F9720D23A5915900C3F17D /* ResetMessage.swift in Sources */,
F85FF3D7252FB1C0004E6FF1 /* SnoozeParametersAccessor.swift in Sources */,
F8C97856242AA86B00A09483 /* CGMMiaoMiaoTransmitterDelegate.swift in Sources */,
F898EDF6234A8A5700BFB79B /* UInt32.swift in Sources */,
F816E0F32433DAA9009EE65B /* BluetoothPeripheralManager+CGMBluconTransmitterDelegate.swift in Sources */,
F8B955B1258BEE9D00C06016 /* ConstantsSpeakReading.swift in Sources */,
F8F9723223A5915900C3F17D /* M5StackReadBlePassWordTxMessage.swift in Sources */,
F8A54AAF22D686CD00934E7A /* NightScoutBgReading.swift in Sources */,
F8DF765323E34F4500063910 /* DexcomG5+CoreDataClass.swift in Sources */,
F8F9720F23A5915900C3F17D /* NSData+CRC.swift in Sources */,
F8A1585722EDB754007F5B5D /* ConstantsCoreData.swift in Sources */,
F80D917224FA9CD5006840B5 /* BluetoothPeripheralManager+CGMLibre2TransmitterDelegate.swift in Sources */,
F8797CEA255B43960033956B /* GlucoseData+Smoothable.swift in Sources */,
F821CF9022AB1068005C1E43 /* DatePickerViewData.swift in Sources */,
F8F9722623A5915900C3F17D /* BluconTransmitterOpCode.swift in Sources */,
@ -3088,10 +3143,12 @@
F8B3A849227F090E004BA588 /* SettingsViewSpeakSettingsViewModel.swift in Sources */,
F8BDD43F221B5BAF006EAB84 /* TextsErrorMessages.swift in Sources */,
F8B3A7FA2278E0E8004BA588 /* SettingsViewModelProtocol.swift in Sources */,
F8A2BC3225DB0D6D001D1E78 /* BluetoothPeripheralManaging.swift in Sources */,
F85DC2F521CFE3D400B9F74A /* BgReading+CoreDataClass.swift in Sources */,
F816E11C2439243B009EE65B /* Droplet+CoreDataProperties.swift in Sources */,
F821CF56229BF43A005C1E43 /* AlertKind.swift in Sources */,
F85DC2ED21CFE2F500B9F74A /* BgReading+CoreDataProperties.swift in Sources */,
F8A2BC0D25DB0B12001D1E78 /* Atom+BluetoothPeripheral.swift in Sources */,
F8F9723123A5915900C3F17D /* M5StackAuthenticateTXMessage.swift in Sources */,
F8F9721223A5915900C3F17D /* FirmwareVersionTxMessage.swift in Sources */,
F80D916824F7086D006840B5 /* Libre2BluetoothPeripheralViewModel.swift in Sources */,
@ -3105,10 +3162,11 @@
F8F9722223A5915900C3F17D /* CRC.swift in Sources */,
F821CF6F229FC280005C1E43 /* Endpoint+NightScout.swift in Sources */,
F8F9722A23A5915900C3F17D /* TransmitterBatteryInfo.swift in Sources */,
F878FA7D2405B3CF00BC6DA6 /* BluetoothPeripheralManager+CGMBubbleTransmitterDelegate.swift in Sources */,
F821CF5D229BF43A005C1E43 /* NSDateFormatter.swift in Sources */,
F8F9721B23A5915900C3F17D /* CGMMiaoMiaoTransmitter.swift in Sources */,
F8F9721A23A5915900C3F17D /* CGMBubbleTransmitter.swift in Sources */,
F8A2BC3B25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMBubbleTransmitterDelegate.swift in Sources */,
F8A2BC3A25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMGNSEntryTransmitterDelegate.swift in Sources */,
F8EA6CA921BBE3010082976B /* UniqueId.swift in Sources */,
F8A1585122EDB597007F5B5D /* ConstantsBGGraphBuilder.swift in Sources */,
F81D6D4822BD5F62005EFAE2 /* DexcomShareUploadManager.swift in Sources */,
@ -3119,15 +3177,14 @@
F80859292364D61B00F3829D /* UserDefaults+charts.swift in Sources */,
F8B955B7258D5E2000C06016 /* ConstantsHealthKit.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 */,
F8E3C3AD21FE551C00907A04 /* DexcomCalibrator.swift in Sources */,
F8C9785B242ABD9800A09483 /* BluetoothPeripheralManager+CGMMiaoMiaoTransmitterDelegate.swift in Sources */,
F8F9723523A5915900C3F17D /* BluetoothTransmitter.swift in Sources */,
F8F9721323A5915900C3F17D /* BatteryStatusRxMessage.swift in Sources */,
F8A2BC3825DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMBluconTransmitterDelegate.swift in Sources */,
F51B9F7D24B216CD00FC0643 /* Libre1NonFixedSlopeCalibrator.swift in Sources */,
F8E51D612448E695001C9E5A /* Bundle.swift in Sources */,
F821CF61229BF4A2005C1E43 /* NightScoutUploadManager.swift in Sources */,
@ -3140,6 +3197,7 @@
F830992323C291EE005741DF /* Watlaa+BluetoothPeripheral.swift in Sources */,
F821CF57229BF43A005C1E43 /* SnoozeParameters.swift in Sources */,
F830992823C32A13005741DF /* TextsWatlaaView.swift in Sources */,
F8A2BC4525DB2679001D1E78 /* AtomResponseType.swift in Sources */,
F8B3A79722635A25004BA588 /* AlertEntry+CoreDataProperties.swift in Sources */,
F830992023C291E2005741DF /* WatlaaBluetoothTransmitter.swift in Sources */,
F8AF36152455C6F700B5977B /* ConstantsTrace.swift in Sources */,
@ -3162,6 +3220,7 @@
F80ED2EC236F68F90005C035 /* SettingsViewM5StackBluetoothSettingsViewModel.swift in Sources */,
F8BECB05235CE5D80060DAE1 /* GlucoseChartManager.swift in Sources */,
F8C97850242A9FD500A09483 /* MiaoMiaoBluetoothPeripheralViewModel.swift in Sources */,
F8A2BC3325DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMDexcomG4TransmitterDelegate.swift in Sources */,
F816E10E2437EAC9009EE65B /* BlueReader+CoreDataProperties.swift in Sources */,
F8B3A830227F085A004BA588 /* SettingsTableViewCell.swift in Sources */,
F82436FC24BE014000BED341 /* TextsLibreStates.swift in Sources */,
@ -3186,6 +3245,7 @@
F897AAFB2201018800CDDD10 /* String.swift in Sources */,
F8B3A847227F090E004BA588 /* SettingsViewNightScoutSettingsViewModel.swift in Sources */,
F8B3A79622635A25004BA588 /* AlertEntry+CoreDataClass.swift in Sources */,
F8A2BC3725DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMMiaoMiaoTransmitterDelegate.swift in Sources */,
F8F7B8E6259A6EBF00C47B04 /* LibreSmoothing.swift in Sources */,
F808D2CA240325E40084B5DB /* CGMBubbleTransmitterDelegate.swift in Sources */,
F804870C2336D90200EBDDB7 /* M5Stack+CoreDataClass.swift in Sources */,
@ -3193,12 +3253,11 @@
F8C97854242AA70D00A09483 /* MiaoMiao+CoreDataProperties.swift in Sources */,
F8F9720A23A5915900C3F17D /* DexcomTransmitterOpCode.swift in Sources */,
F8AC425E21ADEBD60078C348 /* AppDelegate.swift in Sources */,
F8A2BC0825DB09BE001D1E78 /* Atom+CoreDataProperties.swift in Sources */,
F804870D2336D90200EBDDB7 /* M5Stack+CoreDataProperties.swift in Sources */,
F85FF3CD252F9FD7004E6FF1 /* SnoozeParameters+CoreDataProperties.swift in Sources */,
F8F9722F23A5915900C3F17D /* M5StackPacket.swift in Sources */,
F897E25223FC871C0075E0E8 /* BluetoothPeripheralManager+BluetoothTransmitterDelegate.swift in Sources */,
F821CF8E22AB090C005C1E43 /* DatePickerViewController.swift in Sources */,
F816E12E2439E06E009EE65B /* BluetoothPeripheralManager+CGMDexcomG4TransmitterDelegate.swift in Sources */,
F8AF11F324B1279500AE5BA2 /* TextsLibreErrors.swift in Sources */,
F8691888239CEEFA0065B607 /* BluetoothPeripheralViewModel.swift in Sources */,
F8297F4F238DCAD800D74D66 /* BluetoothPeripheralNavigationController.swift in Sources */,
@ -3214,6 +3273,7 @@
F8E6C78C24CDDB83007C1199 /* SnoozeViewController.swift in Sources */,
F8AF11F824B1E6EE00AE5BA2 /* XdripError.swift in Sources */,
F830990523B94ED7005741DF /* TimeScheduleViewController.swift in Sources */,
F8A2BC2F25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMBlueReaderTransmitterDelegate.swift in Sources */,
F8F9722123A5915900C3F17D /* LibreSensorSerialNumber.swift in Sources */,
F8A1586722EDB8BF007F5B5D /* ConstantsHomeView.swift in Sources */,
F8A1585922EDB7C6007F5B5D /* ConstantsDefaultAlertLevels.swift in Sources */,
@ -3236,6 +3296,7 @@
F8B3A808227A2933004BA588 /* SettingsSelectedRowAction.swift in Sources */,
F8A5EEB2257CEC290085E660 /* LibreNFC.swift in Sources */,
F816E0F02433C31B009EE65B /* Blucon+CoreDataProperties.swift in Sources */,
F8A2BC3925DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMLibre2TransmitterDelegate.swift in Sources */,
F8A5EEAE25791F370085E660 /* Libre2BLEUtilities.swift in Sources */,
F8E3C3AB21FE17B700907A04 /* StringProtocol.swift in Sources */,
F8F9720723A5915900C3F17D /* AuthChallengeTxMessage.swift in Sources */,
@ -3259,29 +3320,33 @@
F8E51D67244BAE0E001C9E5A /* WatlaaBluetoothTransmitterMaster+CGMTransmitter.swift in Sources */,
F81FA0002289E4990028C70F /* AlertSettingsViewControllerData.swift in Sources */,
F80D916024F45EB3006840B5 /* LibreError.swift in Sources */,
F8A2BC3625DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMG6TransmitterDelegate.swift in Sources */,
F856CE5B22EDC8E50083E436 /* ConstantsBluetoothPairing.swift in Sources */,
F8F971B823A5914D00C3F17D /* BluetoothPeripheral.swift in Sources */,
F8F9721723A5915900C3F17D /* CGMDroplet1Transmitter.swift in Sources */,
F8A2BC2E25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMDropletTransmitterDelegate.swift in Sources */,
F8C5EBE722F38F0E00563B5F /* Trace.swift in Sources */,
F8B48A9422B2A705009BCC01 /* TextsSpeakReading.swift in Sources */,
F821CF5F229BF43A005C1E43 /* ApplicationManager.swift in Sources */,
F8B3A834227F08AC004BA588 /* PickerViewData.swift in Sources */,
F8177025248ED4DE00AA3600 /* Libre1DerivedAlgorithmParameters.swift in Sources */,
F808592D23677D6A00F3829D /* ChartPoint.swift in Sources */,
F8A2BC0425DB093B001D1E78 /* Atom+CoreDataClass.swift in Sources */,
F8F9722823A5915900C3F17D /* BluconUtilities.swift in Sources */,
F8F9724723A69A8000C3F17D /* BluetoothPeripheralCategory.swift in Sources */,
F8B3A79522635A25004BA588 /* AlertType+CoreDataProperties.swift in Sources */,
F8A2BBFD25D9D386001D1E78 /* AtomBluetoothPeripheralViewModel.swift in Sources */,
F8AF11FA24B1FB3500AE5BA2 /* DexcomError.swift in Sources */,
F8B3A84C227F090E004BA588 /* SettingsViewController.swift in Sources */,
F8F9720B23A5915900C3F17D /* SensorDataRxMessage.swift in Sources */,
F816E10C2437EA8E009EE65B /* BlueReader+CoreDataClass.swift in Sources */,
F8A2BC1425DB0B61001D1E78 /* CGMAtomTransmitter.swift in Sources */,
F8AC426021ADEBD60078C348 /* RootViewController.swift in Sources */,
F897E25023FC871C0075E0E8 /* BluetoothPeripheralManager+CGMG5TransmitterDelegate.swift in Sources */,
F8B3A78B225D473D004BA588 /* UIAlertController.swift in Sources */,
F816E118243921FB009EE65B /* CGMBDropletTransmitterDelegate.swift in Sources */,
F8F9720E23A5915900C3F17D /* AuthRequestRxMessage.swift in Sources */,
F8A2BC3F25DB0D89001D1E78 /* BluetoothPeripheralManager+CGMAtomTransmitterDelegate.swift in Sources */,
F8BDD4242218790E006EAB84 /* UserDefaults.swift in Sources */,
F897E25323FC871C0075E0E8 /* BluetoothPeripheralManager+WatlaaBluetoothTransmitterDelegate.swift in Sources */,
F81D6D5222C27F18005EFAE2 /* BgReading+DexcomShare.swift in Sources */,
F8F9723023A5915900C3F17D /* M5StackUtilities.swift in Sources */,
F8297F52238ECA3200D74D66 /* BluetoothPeripheralViewController.swift in Sources */,
@ -3294,16 +3359,16 @@
F8E6C79024CEC22A007C1199 /* TextsSnooze.swift in Sources */,
F8F9722C23A5915900C3F17D /* GlucoseData.swift in Sources */,
F8A389E7232ECE7E0010F405 /* SettingsViewUtilities.swift in Sources */,
F8A2BC3125DB0D6D001D1E78 /* BluetoothPeripheralManager+M5StackBluetoothTransmitterDelegate.swift in Sources */,
F8A2BC2D25DB0D6D001D1E78 /* BluetoothPeripheralManager+CGMG5TransmitterDelegate.swift in Sources */,
F8B3A7DF226E48C1004BA588 /* SoundPlayer.swift in Sources */,
F816E12C2439DFBA009EE65B /* DexcomG4+CoreDataProperties.swift in Sources */,
F897E25123FC871C0075E0E8 /* BluetoothPeripheralManager+M5StackBluetoothTransmitterDelegate.swift in Sources */,
F8A2BC3425DB0D6D001D1E78 /* BluetoothPeripheralManager+WatlaaBluetoothTransmitterDelegate.swift in Sources */,
F8B3A820227DEC92004BA588 /* AlertTypesAccessor.swift in Sources */,
F8F9720623A5915900C3F17D /* AuthRequestTxMessage.swift in Sources */,
F8F9721123A5915900C3F17D /* KeepAliveTxMessage.swift in Sources */,
F816E10524368BC3009EE65B /* BluetoothPeripheralManager+CGMGNSEntryTransmitterDelegate.swift in Sources */,
F8B3A81E227DEC92004BA588 /* BgReadingsAccessor.swift in Sources */,
F8E51D63244B3386001C9E5A /* MiaoMiaoResponseType.swift in Sources */,
F816E11E24392690009EE65B /* BluetoothPeripheralManager+CGMDropletTransmitterDelegate.swift in Sources */,
F821CF6B229FC22D005C1E43 /* Endpoint.swift in Sources */,
F821CF58229BF43A005C1E43 /* AlertManager.swift in Sources */,
F80D916B24F82913006840B5 /* CGMLibre2Transmitter.swift in Sources */,
@ -3313,6 +3378,7 @@
F816E0E42432A4FA009EE65B /* CGMBluconTransmitterDelegate.swift in Sources */,
F8A389CF232AE2EA0010F405 /* M5StackSettingsViewController.swift in Sources */,
F821CF5E229BF43A005C1E43 /* BgReading+NightScout.swift in Sources */,
F8A2BC3025DB0D6D001D1E78 /* BluetoothPeripheralManager.swift in Sources */,
F8A389EB233175A10010F405 /* SettingsViewM5StackSettingsViewModel.swift in Sources */,
F816E1242439DB63009EE65B /* DexcomG4+BluetoothPeripheral.swift in Sources */,
F8E5404C2522624800052CE5 /* ConstantsHousekeeping.swift in Sources */,
@ -3321,18 +3387,17 @@
F8025C1321DA683400ECF0C0 /* Data.swift in Sources */,
F825286A2443AE190067AF77 /* DexcomG6BluetoothPeripheralViewModel.swift in Sources */,
F80859272364355F00F3829D /* ConstantsGlucoseChart.swift in Sources */,
F825286E2443C1000067AF77 /* BluetoothPeripheralManager+CGMG6TransmitterDelegate.swift in Sources */,
F816E10324367389009EE65B /* GNSEntryBluetoothPeripheralViewModel.swift in Sources */,
F8E51D5D2448D8B5001C9E5A /* LoopManager.swift in Sources */,
F8DF766D23ED9B0900063910 /* DexcomG5BluetoothPeripheralViewModel.swift in Sources */,
F8E51D65244BA790001C9E5A /* WatlaaBluetoothPeripheralViewModel.swift in Sources */,
F85DC2EF21CFE2F500B9F74A /* Sensor+CoreDataProperties.swift in Sources */,
F8297F56238ED07700D74D66 /* BluetoothPeripheralManager.swift in Sources */,
F8297F5A238EE14E00D74D66 /* TextsBluetoothPeripheralView.swift in Sources */,
F8BECB02235CE3E20060DAE1 /* BloodGlucoseChartView.swift in Sources */,
F8A1584D22ECA445007F5B5D /* SettingsViewDevelopmentSettingsViewModel.swift in Sources */,
F816E12A2439DF3A009EE65B /* DexcomG4+CoreDataClass.swift in Sources */,
F8F9723E23A593C000C3F17D /* M5StickCBluetoothPeripheralViewModel.swift in Sources */,
F8A2BC3525DB0D6D001D1E78 /* BluetoothPeripheralManager+BluetoothTransmitterDelegate.swift in Sources */,
F8F9722323A5915900C3F17D /* LibreDataParser.swift in Sources */,
F8E51D5F2448E2E8001C9E5A /* ConstantsShareWithLoop.swift in Sources */,
F816E0ED2432A55F009EE65B /* BluconBluetoothPeripheralViewModel.swift in Sources */,
@ -3844,7 +3909,7 @@
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 4.5.18;
PRODUCT_BUNDLE_IDENTIFIER = "com.${DEVELOPMENT_TEAM}.xdripswift.xDrip4iOS-Widget";
PRODUCT_BUNDLE_IDENTIFIER = "com.${DEVELOPMENT_TEAM}.xDrip4iOS-Widget";
PRODUCT_NAME = xDrip4iOS;
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
@ -3869,7 +3934,7 @@
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 4.5.18;
PRODUCT_BUNDLE_IDENTIFIER = "com.${DEVELOPMENT_TEAM}.xdripswift.xDrip4iOS-Widget";
PRODUCT_BUNDLE_IDENTIFIER = "com.${DEVELOPMENT_TEAM}.xDrip4iOS-Widget";
PRODUCT_NAME = xDrip4iOS;
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
@ -4092,12 +4157,13 @@
F85FF3C2252D0C32004E6FF1 /* xdrip.xcdatamodeld */ = {
isa = XCVersionGroup;
children = (
F8A2BC0225D9D471001D1E78 /* xdrip v16.xcdatamodel */,
F87F5EFD2560686C00FFA395 /* xdrip v15.xcdatamodel */,
F83275882546225400D305E6 /* xdrip v14.xcdatamodel */,
F85FF3CB252F9C9A004E6FF1 /* xdrip v13.xcdatamodel */,
F85FF3C3252D0C32004E6FF1 /* xdrip v12.xcdatamodel */,
);
currentVersion = F87F5EFD2560686C00FFA395 /* xdrip v15.xcdatamodel */;
currentVersion = F8A2BC0225D9D471001D1E78 /* xdrip v16.xcdatamodel */;
path = xdrip.xcdatamodeld;
sourceTree = "<group>";
versionGroupType = wrapper.xcdatamodel;

View File

@ -0,0 +1,11 @@
import Foundation
extension Atom: BluetoothPeripheral {
func bluetoothPeripheralType() -> BluetoothPeripheralType {
return .AtomType
}
}

View File

@ -45,6 +45,9 @@ enum BluetoothPeripheralType: String, CaseIterable {
/// Libre 2
case Libre2Type = "Libre 2"
/// Atom
case AtomType = "Atom"
/// - returns: the BluetoothPeripheralViewModel. If nil then there's no specific settings for the tpe of bluetoothPeripheral
func viewModel() -> BluetoothPeripheralViewModel? {
@ -90,6 +93,9 @@ enum BluetoothPeripheralType: String, CaseIterable {
case .Libre2Type:
return Libre2BluetoothPeripheralViewModel()
case .AtomType:
return AtomBluetoothPeripheralViewModel()
}
}
@ -159,6 +165,10 @@ enum BluetoothPeripheralType: String, CaseIterable {
return Libre2(address: address, name: name, alias: nil, nsManagedObjectContext: nsManagedObjectContext)
case .AtomType:
return Atom(address: address, name: name, alias: nil, nsManagedObjectContext: nsManagedObjectContext)
}
}
@ -171,7 +181,7 @@ enum BluetoothPeripheralType: String, CaseIterable {
case .M5StackType, .M5StickCType:
return .M5Stack
case .DexcomG5Type, .BubbleType, .MiaoMiaoType, .BluconType, .GNSentryType, .BlueReaderType, .DropletType, .DexcomG4Type, .DexcomG6Type, .WatlaaType, .Libre2Type:
case .DexcomG5Type, .BubbleType, .MiaoMiaoType, .BluconType, .GNSentryType, .BlueReaderType, .DropletType, .DexcomG4Type, .DexcomG6Type, .WatlaaType, .Libre2Type, .AtomType:
return .CGM
}
@ -183,7 +193,7 @@ enum BluetoothPeripheralType: String, CaseIterable {
switch self {
case .M5StackType, .M5StickCType, .WatlaaType, .BubbleType, .MiaoMiaoType, .GNSentryType, .BlueReaderType, .DropletType, .Libre2Type:
case .M5StackType, .M5StickCType, .WatlaaType, .BubbleType, .MiaoMiaoType, .GNSentryType, .BlueReaderType, .DropletType, .Libre2Type, .AtomType:
return false
case .DexcomG5Type, .BluconType, .DexcomG4Type, .DexcomG6Type:
@ -233,7 +243,7 @@ enum BluetoothPeripheralType: String, CaseIterable {
}
return nil
case .M5StackType, .M5StickCType, .WatlaaType, .BubbleType, .MiaoMiaoType, .GNSentryType, .BlueReaderType, .DropletType, .Libre2Type:
case .M5StackType, .M5StickCType, .WatlaaType, .BubbleType, .MiaoMiaoType, .GNSentryType, .BlueReaderType, .DropletType, .Libre2Type, .AtomType:
// no transmitter id means no validation to do
return nil
@ -261,7 +271,7 @@ enum BluetoothPeripheralType: String, CaseIterable {
case .M5StackType, .M5StickCType, .WatlaaType, .DexcomG4Type, .DexcomG5Type, .DexcomG6Type, .BluconType, .BlueReaderType, .DropletType , .GNSentryType:
return false
case .BubbleType, .MiaoMiaoType:
case .BubbleType, .MiaoMiaoType, .AtomType:
return true
case .Libre2Type:
@ -280,7 +290,7 @@ enum BluetoothPeripheralType: String, CaseIterable {
case .M5StackType, .M5StickCType, .DexcomG4Type, .DexcomG5Type, .DexcomG6Type:
return false
case .BubbleType, .MiaoMiaoType, .WatlaaType, .BluconType, .BlueReaderType, .DropletType , .GNSentryType:
case .BubbleType, .MiaoMiaoType, .WatlaaType, .BluconType, .BlueReaderType, .DropletType , .GNSentryType, .AtomType:
return true
case .Libre2Type:

View File

@ -60,6 +60,9 @@ enum CGMTransmitterType:String, CaseIterable {
/// BlueReader
case blueReader = "BlueReader"
/// Atom
case Atom = "Atom"
/// watlaa
case watlaa = "Watlaa"
@ -74,7 +77,7 @@ enum CGMTransmitterType:String, CaseIterable {
case .dexcomG4, .dexcomG5, .dexcomG6 :
return .Dexcom
case .miaomiao, .Bubble, .GNSentry, .Droplet1, .blueReader, .watlaa, .Blucon, .Libre2:
case .miaomiao, .Bubble, .GNSentry, .Droplet1, .blueReader, .watlaa, .Blucon, .Libre2, .Atom:
return .Libre
}
@ -117,6 +120,9 @@ enum CGMTransmitterType:String, CaseIterable {
case .Libre2:
return true
case .Atom:
return true
}
}
@ -130,7 +136,7 @@ enum CGMTransmitterType:String, CaseIterable {
case .dexcomG4, .dexcomG5, .dexcomG6, .GNSentry, .Droplet1, .blueReader, .watlaa:
return true
case .miaomiao, .Bubble, .Blucon, .Libre2:
case .miaomiao, .Bubble, .Blucon, .Libre2, .Atom:
return true
@ -171,6 +177,9 @@ enum CGMTransmitterType:String, CaseIterable {
case .Libre2:
return ConstantsDefaultAlertLevels.defaultBatteryAlertLevelLibre2
case .Atom:
return ConstantsDefaultAlertLevels.defaultBatteryAlertLevelAtom
}
}
@ -205,6 +214,9 @@ enum CGMTransmitterType:String, CaseIterable {
case .Libre2:
return "%"
case .Atom:
return "%"
}
}

View File

@ -0,0 +1,26 @@
import Foundation
enum AtomResponseType: UInt8 {
case transmitterInfo = 0x80
case sensorUID = 0xC0
case patchInfo = 0xC1
case dataPacket = 0x82
case sensorNotDetected = 0xBF
}
extension AtomResponseType: CustomStringConvertible {
public var description: String {
switch self {
case .transmitterInfo:
return "Transmitter Info received"
case .sensorUID:
return "Sensor UID received"
case .patchInfo:
return "patchInfo detected"
case .dataPacket:
return "dataPacket received"
case .sensorNotDetected:
return "Sensor not detected"
}
}
}

View File

@ -0,0 +1,431 @@
import Foundation
import CoreBluetooth
import os
class CGMAtomTransmitter:BluetoothTransmitter, CGMTransmitter {
// MARK: - properties
/// service to be discovered
let CBUUID_Service_Atom: String = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
/// receive characteristic
let CBUUID_ReceiveCharacteristic_Atom: String = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
/// write characteristic
let CBUUID_WriteCharacteristic_Atom: String = "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
/// expected device name
let expectedDeviceNameAtom:String = "Atom"
/// will be used to pass back bluetooth and cgm related events
private(set) weak var cgmTransmitterDelegate:CGMTransmitterDelegate?
/// CGMAtomTransmitterDelegate
public weak var cGMAtomTransmitterDelegate: CGMAtomTransmitterDelegate?
// maximum times resend request due to crc error
let maxPacketResendRequests = 3;
/// for trace
private let log = OSLog(subsystem: ConstantsLog.subSystem, category: ConstantsLog.categoryCGMAtom)
/// counts number of times resend was requested due to crc error
private var resendPacketCounter:Int = 0
/// used when processing Atom data packet
private var timestampLastPacketReception:Date
/// receive buffer for atom packets
private var rxBuffer:Data
/// how long to wait for next packet before sending startreadingcommand
private static let maxWaitForpacketInSeconds = 3.0
/// is the transmitter oop web enabled or not
private var webOOPEnabled: Bool
/// is nonFixed enabled for the transmitter or not
private var nonFixedSlopeEnabled: Bool
/// - current sensor serial number, if nil then it's not known yet
/// - stored as data because serial number is recalculated when patchInfo is received
private var sensorSerialNumberAsData: Data?
/// used as parameter in call to cgmTransmitterDelegate.cgmTransmitterInfoReceived, when there's no glucosedata to send
var emptyArray: [GlucoseData] = []
/// instance of libreDataParser
private let libreDataParser: LibreDataParser
// gives information about type of sensor (Libre1, Libre2, etc..)
private var patchInfo: String?
/// firmware, if received
private var firmWare: String?
// 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
/// - webOOPEnabled : enabled or not
/// - bluetoothTransmitterDelegate : a BluetoothTransmitterDelegate
/// - cGMTransmitterDelegate : a CGMTransmitterDelegate
/// - cGMAtomTransmitterDelegate : a CGMAtomTransmitterDelegate
/// - firmWare : firmWare if known
init(address:String?, name: String?, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate, cGMAtomTransmitterDelegate : CGMAtomTransmitterDelegate, cGMTransmitterDelegate:CGMTransmitterDelegate, webOOPEnabled: Bool?, nonFixedSlopeEnabled: Bool?, firmWare: String?) {
// assign addressname and name or expected devicename
var newAddressAndName:BluetoothTransmitter.DeviceAddressAndName = BluetoothTransmitter.DeviceAddressAndName.notYetConnected(expectedName: expectedDeviceNameAtom)
if let address = address {
newAddressAndName = BluetoothTransmitter.DeviceAddressAndName.alreadyConnectedBefore(address: address, name: name)
}
// assign firmWare
self.firmWare = firmWare
// assign CGMTransmitterDelegate
self.cgmTransmitterDelegate = cGMTransmitterDelegate
// assign cGMAtomTransmitterDelegate
self.cGMAtomTransmitterDelegate = cGMAtomTransmitterDelegate
// initialize rxbuffer
rxBuffer = Data()
timestampLastPacketReception = Date()
// initialize webOOPEnabled
self.webOOPEnabled = webOOPEnabled ?? false
// initialize nonFixedSlopeEnabled
self.nonFixedSlopeEnabled = nonFixedSlopeEnabled ?? false
// initiliaze LibreDataParser
self.libreDataParser = LibreDataParser()
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: nil, servicesCBUUIDs: [CBUUID(string: CBUUID_Service_Atom)], CBUUID_ReceiveCharacteristic: CBUUID_ReceiveCharacteristic_Atom, CBUUID_WriteCharacteristic: CBUUID_WriteCharacteristic_Atom, bluetoothTransmitterDelegate: bluetoothTransmitterDelegate)
}
// MARK: - public functions
func sendStartReadingCommand() -> Bool {
if writeDataToPeripheral(data: Data.init([0x00, 0x01, 0x05]), type: .withoutResponse) {
return true
} else {
trace("in sendStartReadingCommand, write failed", log: log, category: ConstantsLog.categoryCGMAtom, type: .error)
return false
}
}
func sendAtomResponse() -> Bool {
if writeDataToPeripheral(data: Data.init([0x02, 0x01, 0x00, 0x00, 0x00, 0x2B]), type: .withoutResponse) {
return true
} else {
trace("in sendAtomResponse, write failed", log: log, category: ConstantsLog.categoryCGMAtom, type: .error)
return false
}
}
// MARK: - overriden BluetoothTransmitter functions
override func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
super.peripheral(peripheral, didUpdateNotificationStateFor: characteristic, error: error)
if error == nil && characteristic.isNotifying {
_ = sendStartReadingCommand()
}
}
override func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
super.peripheral(peripheral, didUpdateValueFor: characteristic, error: error)
if let value = characteristic.value {
//check if buffer needs to be reset
if (Date() > timestampLastPacketReception.addingTimeInterval(CGMAtomTransmitter.maxWaitForpacketInSeconds)) {
trace("in peripheral didUpdateValueFor, more than %{public}@ seconds since last update - or first update since app launch, resetting buffer", log: log, category: ConstantsLog.categoryCGMAtom, type: .info, CGMAtomTransmitter.maxWaitForpacketInSeconds.description)
resetRxBuffer()
}
// set timestampLastPacketReception to now, this gives the MM again maxWaitForpacketInSeconds seconds to send the next packet
timestampLastPacketReception = Date()
//check type of message and process according to type
if let firstByte = value.first {
if let atomResponseState = AtomResponseType(rawValue: firstByte) {
switch atomResponseState {
case .dataPacket:
//add new packet to buffer, ignore the first 4 bytes
rxBuffer.append(value[4..<value.endIndex])
//if buffer complete, then start processing
if rxBuffer.count >= 344 {
trace("in peripheral didUpdateValueFor, Buffer complete", log: log, category: ConstantsLog.categoryCGMAtom, type: .info)
var dataIsDecryptedToLibre1Format = false
if let libreSensorType = LibreSensorType.type(patchInfo: patchInfo) {
// note that we should always have a libreSensorType
// decrypt of libre2 or libreUS
dataIsDecryptedToLibre1Format = libreSensorType.decryptIfPossibleAndNeeded(rxBuffer: &rxBuffer[0..<344], headerLength: 0, log: log, patchInfo: patchInfo, uid: rxBuffer[5..<13].bytes)
// now except libreProH, all libres' 344 data is libre1 format
// should crc check
guard libreSensorType.crcIsOk(rxBuffer: &self.rxBuffer[0..<344], headerLength: 0, log: log) else {
let temp = resendPacketCounter
resetRxBuffer()
resendPacketCounter = temp + 1
if resendPacketCounter < maxPacketResendRequests {
trace("in peripheral didUpdateValueFor, crc error encountered. New attempt launched", log: log, category: ConstantsLog.categoryCGMAtom, type: .info)
_ = sendStartReadingCommand()
} else {
trace("in peripheral didUpdateValueFor, crc error encountered. Maximum nr of attempts reached", log: log, category: ConstantsLog.categoryCGMAtom, type: .info)
resendPacketCounter = 0
}
return
}
}
guard let sensorSerialNumberAsData = sensorSerialNumberAsData else {
trace("in peripheral didUpdateValueFor, sensorSerialNumberAsData is nil, no further processing", log: log, category: ConstantsLog.categoryCGMAtom, type: .error)
return
}
libreDataParser.libreDataProcessor(libreSensorSerialNumber: LibreSensorSerialNumber(withUID: sensorSerialNumberAsData, with: LibreSensorType.type(patchInfo: patchInfo)), patchInfo: patchInfo, webOOPEnabled: webOOPEnabled, libreData: (rxBuffer[0..<344]), cgmTransmitterDelegate: cgmTransmitterDelegate, dataIsDecryptedToLibre1Format: dataIsDecryptedToLibre1Format, testTimeStamp: nil, completionHandler: { (sensorState: LibreSensorState?, xDripError: XdripError?) in
if let sensorState = sensorState {
self.cGMAtomTransmitterDelegate?.received(sensorStatus: sensorState, from: self)
}
})
//reset the buffer
resetRxBuffer()
}
case .transmitterInfo:
trace("in peripheral didUpdateValueFor, transmitterInfo received, shound't happen ?", log: log, category: ConstantsLog.categoryCGMAtom, type: .error)
let transmitterBatteryPercentage = Int(value[4])
// send transmitterBatteryInfo to cgmTransmitterDelegate
cgmTransmitterDelegate?.cgmTransmitterInfoReceived(glucoseData: &emptyArray, transmitterBatteryInfo: TransmitterBatteryInfo.percentage(percentage: transmitterBatteryPercentage), sensorTimeInMinutes: nil)
// send transmitter battery percentage to cGMAtomTransmitterDelegate
cGMAtomTransmitterDelegate?.received(batteryLevel: transmitterBatteryPercentage, from: self)
// get firmware, byte 2 to hex + "." + byte 3 to hex
firmWare = String(describing: value[2..<3].hexEncodedString()) + "." + String(describing: value[3..<4].hexEncodedString())
// send firmware to cGMAtomTransmitterDelegate
if let firmWare = firmWare {
cGMAtomTransmitterDelegate?.received(firmware: firmWare, from: self)
}
// get hardware, last but one byte to hex + "." + last byte to hex
let hardWare = String(describing: value[(value.count - 2)..<(value.count - 1)].hexEncodedString()) + "." + String(describing: value[(value.count - 1)..<value.count].hexEncodedString())
// send hardware to cGMAtomTransmitterDelegate
cGMAtomTransmitterDelegate?.received(hardware: hardWare, from: self)
// send ack message
_ = sendAtomResponse()
case .sensorNotDetected:
trace("in peripheral didUpdateValueFor, received sensorNotDetected", log: log, category: ConstantsLog.categoryCGMAtom, type: .info)
// call cgmTransmitterDelegate sensorNotDetected
cgmTransmitterDelegate?.sensorNotDetected()
case .sensorUID:
trace("in peripheral didUpdateValueFor, received sensorUID", log: log, category: ConstantsLog.categoryCGMAtom, type: .info)
guard value.count >= 10 else {
trace("in peripheral didUpdateValueFor, received sensorUID, not enough bytes received", log: log, category: ConstantsLog.categoryCGMAtom, type: .error)
return
}
// assign self.serialNumber
self.sensorSerialNumberAsData = value[2..<10]
guard let sensorSerialNumberAsData = sensorSerialNumberAsData, let libreSensorSerialNumber = LibreSensorSerialNumber(withUID: sensorSerialNumberAsData, with: LibreSensorType.type(patchInfo: patchInfo)) else {
trace("in peripheral didUpdateValueFor, could not create libreSensorSerialNumber", log: self.log, category: ConstantsLog.categoryCGMBubble, type: .info)
return
}
// call to delegate, received sensor serialNumber
cGMAtomTransmitterDelegate?.received(serialNumber: libreSensorSerialNumber.serialNumber, from: self)
case .patchInfo:
trace("in peripheral didUpdateValueFor, received patchInfo", log: log, category: ConstantsLog.categoryCGMAtom, type: .info)
guard let firmWare = firmWare, let firmWareAsDouble = firmWare.toDouble() else {
trace("in peripheral didUpdateValueFor, firmware nil or not convertible to double", log: log, category: ConstantsLog.categoryCGMAtom, type: .error)
return
}
if firmWareAsDouble < 1.35 && value.count >= 9 {
patchInfo = value[3..<9].hexEncodedString().uppercased()
} else if value.count >= 11 {
patchInfo = value[5..<11].hexEncodedString().uppercased()
}
if let patchInfo = patchInfo {
trace(" received patchInfo %{public}@ ", log: log, category: ConstantsLog.categoryCGMBubble, type: .info, patchInfo)
}
// send libreSensorType to delegate
if let libreSensorType = LibreSensorType.type(patchInfo: patchInfo) {
cGMAtomTransmitterDelegate?.received(libreSensorType: libreSensorType, from: self)
}
// recalculate serial number and send to delegate
if let sensorSerialNumberAsData = sensorSerialNumberAsData, let libreSensorSerialNumber = LibreSensorSerialNumber(withUID: sensorSerialNumberAsData, with: LibreSensorType.type(patchInfo: patchInfo)) {
// call to delegate, received sensor serialNumber
cGMAtomTransmitterDelegate?.received(serialNumber: libreSensorSerialNumber.serialNumber, from: self)
}
}
} else {
//value doesn't start with a known atomresponse
//reset the buffer
trace("in peripheral didUpdateValueFor, rx buffer doesn't start with a known atomresponse, reset the buffer", log: log, category: ConstantsLog.categoryCGMAtom, type: .error)
resetRxBuffer()
}
}
} else {
trace("in peripheral didUpdateValueFor, value is nil, no further processing", log: log, category: ConstantsLog.categoryCGMAtom, type: .error)
}
}
// MARK: - helpers
/// reset rxBuffer, reset startDate, set resendPacketCounter to 0
private func resetRxBuffer() {
rxBuffer = Data()
timestampLastPacketReception = Date()
resendPacketCounter = 0
}
// MARK: - CGMTransmitter protocol functions
/// this transmitter supports oopWeb
func setWebOOPEnabled(enabled: Bool) {
webOOPEnabled = enabled
// immediately request a new reading
// there's no check here to see if peripheral, characteristic, connection, etc.. exists, but that's no issue. If anything's missing, write will simply fail,
_ = sendStartReadingCommand()
}
func isWebOOPEnabled() -> Bool {
return webOOPEnabled
}
func setNonFixedSlopeEnabled(enabled: Bool) {
nonFixedSlopeEnabled = enabled
// immediately request a new reading
// there's no check here to see if peripheral, characteristic, connection, etc.. exists, but that's no issue. If anything's missing, write will simply fail,
_ = sendStartReadingCommand()
}
func isNonFixedSlopeEnabled() -> Bool {
return nonFixedSlopeEnabled
}
func requestNewReading() {
_ = sendStartReadingCommand()
}
func cgmTransmitterType() -> CGMTransmitterType {
return .Atom
}
}

View File

@ -0,0 +1,24 @@
import Foundation
protocol CGMAtomTransmitterDelegate: AnyObject {
/// received firmware
func received(firmware: String, from cGMAtomTransmitter: CGMAtomTransmitter)
/// received hardware
func received(hardware: String, from cGMAtomTransmitter: CGMAtomTransmitter)
/// received sensor Serial Number
func received(serialNumber: String, from cGMAtomTransmitter: CGMAtomTransmitter)
/// Atom is sending batteryLevel
func received(batteryLevel: Int, from cGMAtomTransmitter: CGMAtomTransmitter)
/// miaomiao is sending type of transmitter
func received(libreSensorType: LibreSensorType, from cGMAtomTransmitter: CGMAtomTransmitter)
/// miaomiao is sending sensorStatus
func received(sensorStatus: LibreSensorState, from cGMAtomTransmitter: CGMAtomTransmitter)
}

View File

@ -11,6 +11,7 @@ enum ConstantsDefaultAlertLevels {
static let defaultBatteryAlertLevelBlueReader = 20
static let defaultBatteryAlertLevelWatlaa = 20
static let defaultBatteryAlertLevelLibre2 = 20
static let defaultBatteryAlertLevelAtom = 20
// blood glucose level alert values in mgdl
static let veryHigh = 250

View File

@ -106,6 +106,9 @@ enum ConstantsLog {
/// bluereader
static let categoryCGMBlueReader = "CGMBlueReader "
/// atom
static let categoryCGMAtom = "categoryCGMAtom "
/// LibreOOPClient
static let categoryLibreOOPClient = "LibreOOPClient "

View File

@ -0,0 +1,42 @@
import Foundation
import CoreData
public class Atom: NSManagedObject {
/// batterylevel, not stored in coreData, will only be available after having received it from the M5Stack
public var batteryLevel: Int = 0
// sensorState
public var sensorState: LibreSensorState = .unknown
/// create Atom
/// - parameters:
init(address: String, name: String, alias: String?, nsManagedObjectContext:NSManagedObjectContext) {
let entity = NSEntityDescription.entity(forEntityName: "Atom", in: nsManagedObjectContext)!
super.init(entity: entity, insertInto: nsManagedObjectContext)
blePeripheral = BLEPeripheral(address: address, name: name, alias: nil, nsManagedObjectContext: nsManagedObjectContext)
}
/// create Atom
/// - parameters:
init(address: String, name: String, alias: String?, sensorSerialNumber: String?, webOOPEnabled: Bool, nsManagedObjectContext:NSManagedObjectContext) {
let entity = NSEntityDescription.entity(forEntityName: "Atom", in: nsManagedObjectContext)!
super.init(entity: entity, insertInto: nsManagedObjectContext)
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)
}
}

View File

@ -0,0 +1,19 @@
import Foundation
import CoreData
extension Atom {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Atom> {
return NSFetchRequest<Atom>(entityName: "Atom")
}
// blePeripheral is required to conform to protocol BluetoothPeripheral
@NSManaged public var blePeripheral: BLEPeripheral
/// firmware
@NSManaged public var firmware: String?
/// hardware
@NSManaged public var hardware: String?
}

View File

@ -64,6 +64,9 @@ extension BLEPeripheral {
// a BLEPeripheral should only have one of dexcomG5, watlaa, m5Stack, ...
@NSManaged public var libre2: Libre2?
// a BLEPeripheral should only have one of dexcomG5, watlaa, m5Stack, ...
@NSManaged public var atom: Atom?
/// sensorSerialNumber of last sensor that was read
@NSManaged public var sensorSerialNumber: String?

View File

@ -3,6 +3,6 @@
<plist version="1.0">
<dict>
<key>_XCCurrentVersionName</key>
<string>xdrip v15.xcdatamodel</string>
<string>xdrip v16.xcdatamodel</string>
</dict>
</plist>

View File

@ -0,0 +1,177 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="17709" systemVersion="20C69" 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="Nullify" 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="Deny" destinationEntity="AlertEntry" inverseName="alertType" inverseEntity="AlertEntry"/>
</entity>
<entity name="Atom" representedClassName=".Atom" syncable="YES">
<attribute name="firmware" optional="YES" attributeType="String"/>
<attribute name="hardware" optional="YES" attributeType="String"/>
<relationship name="blePeripheral" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="BLEPeripheral" inverseName="atom" inverseEntity="BLEPeripheral"/>
</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="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="atom" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Atom" inverseName="blePeripheral" inverseEntity="Atom"/>
<relationship name="blucon" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="Blucon" inverseName="blePeripheral" inverseEntity="Blucon"/>
<relationship name="blueReader" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="BlueReader" inverseName="blePeripheral" inverseEntity="BlueReader"/>
<relationship name="bubble" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="Bubble" inverseName="blePeripheral" inverseEntity="Bubble"/>
<relationship name="dexcomG4" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="DexcomG4" inverseName="blePeripheral" inverseEntity="DexcomG4"/>
<relationship name="dexcomG5" optional="YES" maxCount="1" deletionRule="Cascade" 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="Cascade" destinationEntity="GNSEntry" inverseName="blePeripheral" inverseEntity="GNSEntry"/>
<relationship name="libre2" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="Libre2" inverseName="blePeripheral" inverseEntity="Libre2"/>
<relationship name="m5Stack" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="M5Stack" inverseName="blePeripheral" inverseEntity="M5Stack"/>
<relationship name="miaoMiao" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="MiaoMiao" inverseName="blePeripheral" inverseEntity="MiaoMiao"/>
<relationship name="watlaa" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="Watlaa" inverseName="blePeripheral" inverseEntity="Watlaa"/>
</entity>
<entity name="Blucon" representedClassName=".Blucon" syncable="YES">
<relationship name="blePeripheral" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="BLEPeripheral" inverseName="blucon" inverseEntity="BLEPeripheral"/>
</entity>
<entity name="BlueReader" representedClassName=".BlueReader" syncable="YES">
<relationship name="blePeripheral" optional="YES" maxCount="1" deletionRule="Cascade" 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"/>
<relationship name="blePeripheral" optional="YES" maxCount="1" deletionRule="Cascade" 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="Cascade" 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="Cascade" 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"/>
<relationship name="blePeripheral" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="BLEPeripheral" inverseName="gNSEntry" inverseEntity="BLEPeripheral"/>
</entity>
<entity name="Libre2" representedClassName=".Libre2" syncable="YES">
<relationship name="blePeripheral" optional="YES" maxCount="1" deletionRule="Cascade" 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"/>
<relationship name="blePeripheral" optional="YES" maxCount="1" deletionRule="Cascade" 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="SnoozeParameters" representedClassName=".SnoozeParameters" syncable="YES">
<attribute name="alertKind" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="snoozePeriodInMinutes" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="snoozeTimeStamp" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
</entity>
<entity name="Watlaa" representedClassName=".Watlaa" syncable="YES">
<attribute name="firmware" optional="YES" attributeType="String"/>
<attribute name="hardware" optional="YES" attributeType="String"/>
<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="28"/>
<element name="AlertType" positionX="-657" positionY="180" width="128" height="28"/>
<element name="BgReading" positionX="-285.87109375" positionY="31.9921875" width="128" height="298"/>
<element name="BLEPeripheral" positionX="-630" positionY="216" width="128" height="359"/>
<element name="Blucon" positionX="-657" positionY="189" width="128" height="58"/>
<element name="BlueReader" positionX="-639" positionY="207" width="128" height="58"/>
<element name="Bubble" positionX="-657" positionY="189" width="128" height="88"/>
<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="103"/>
<element name="Libre2" positionX="-648" positionY="198" width="128" height="58"/>
<element name="M5Stack" positionX="-657" positionY="180" width="128" height="163"/>
<element name="MiaoMiao" positionX="-657" positionY="189" width="128" height="88"/>
<element name="Sensor" positionX="-603.0859375" positionY="482.2890625" width="128" height="133"/>
<element name="SnoozeParameters" positionX="-648" positionY="198" width="128" height="28"/>
<element name="Watlaa" positionX="-639" positionY="207" width="128" height="88"/>
<element name="Atom" positionX="-657" positionY="189" width="128" height="74"/>
</elements>
</model>

View File

@ -0,0 +1,81 @@
import Foundation
extension BluetoothPeripheralManager: CGMAtomTransmitterDelegate {
func received(sensorStatus: LibreSensorState, from cGMAtomTransmitter: CGMAtomTransmitter) {
guard let atom = findTransmitter(cGMAtomTransmitter: cGMAtomTransmitter) else {return}
// store serial number in atom object
atom.sensorState = sensorStatus
// no coredatamanager savechanges needed because batterylevel is not stored in coredata
}
func received(libreSensorType: LibreSensorType, from cGMAtomTransmitter: CGMAtomTransmitter) {
guard let atom = findTransmitter(cGMAtomTransmitter: cGMAtomTransmitter) else {return}
// store libreSensorType in atom.blePeripheral object
atom.blePeripheral.libreSensorType = libreSensorType
// coredatamanager savechanges needed because webOOPEnabled is stored in coredata
coreDataManager.saveChanges()
}
func received(batteryLevel: Int, from cGMAtomTransmitter: CGMAtomTransmitter) {
guard let atom = findTransmitter(cGMAtomTransmitter: cGMAtomTransmitter) else {return}
// store serial number in atom object
atom.batteryLevel = batteryLevel
// no coredatamanager savechanges needed because batterylevel is not stored in coredata
}
func received(serialNumber: String, from cGMAtomTransmitter: CGMAtomTransmitter) {
guard let atom = findTransmitter(cGMAtomTransmitter: cGMAtomTransmitter) else {return}
// store serial number in atom object
atom.blePeripheral.sensorSerialNumber = serialNumber
coreDataManager.saveChanges()
}
func received(firmware: String, from cGMAtomTransmitter: CGMAtomTransmitter) {
guard let atom = findTransmitter(cGMAtomTransmitter: cGMAtomTransmitter) else {return}
// store firmware in atom object
atom.firmware = firmware
coreDataManager.saveChanges()
}
func received(hardware: String, from cGMAtomTransmitter: CGMAtomTransmitter) {
guard let atom = findTransmitter(cGMAtomTransmitter: cGMAtomTransmitter) else {return}
// store hardware in atom object
atom.hardware = hardware
coreDataManager.saveChanges()
}
private func findTransmitter(cGMAtomTransmitter: CGMAtomTransmitter) -> Atom? {
guard let index = bluetoothTransmitters.firstIndex(of: cGMAtomTransmitter), let atom = bluetoothPeripherals[index] as? Atom else {return nil}
return atom
}
}

View File

@ -247,6 +247,33 @@ class BluetoothPeripheralManager: NSObject {
}
case .AtomType:
if let atom = blePeripheral.atom {
// add it to the list of bluetoothPeripherals
let index = insertInBluetoothPeripherals(bluetoothPeripheral: atom)
if atom.blePeripheral.shouldconnect {
// create an instance of CGMAtomTransmitter, CGMAtomTransmitter 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(CGMAtomTransmitter(address: atom.blePeripheral.address, name: atom.blePeripheral.name, bluetoothTransmitterDelegate: self, cGMAtomTransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, webOOPEnabled: atom.blePeripheral.webOOPEnabled, nonFixedSlopeEnabled: atom.blePeripheral.nonFixedSlopeEnabled, firmWare: atom.firmware), at: index)
// if AtomType 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 .DexcomG4Type:
if let dexcomG4 = blePeripheral.dexcomG4 {
@ -486,7 +513,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, .Libre2Type:
case .DexcomG5Type, .BubbleType, .MiaoMiaoType, .BluconType, .GNSentryType, .BlueReaderType, .DropletType, .DexcomG4Type, .DexcomG6Type, .Libre2Type, .AtomType:
// cgm's don't receive reading, they send it
break
@ -622,6 +649,21 @@ class BluetoothPeripheralManager: NSObject {
}
}
case .AtomType:
if let atom = bluetoothPeripheral as? Atom {
if let cgmTransmitterDelegate = cgmTransmitterDelegate {
newTransmitter = CGMAtomTransmitter(address: atom.blePeripheral.address, name: atom.blePeripheral.name, bluetoothTransmitterDelegate: self, cGMAtomTransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, webOOPEnabled: atom.blePeripheral.webOOPEnabled, nonFixedSlopeEnabled: atom.blePeripheral.nonFixedSlopeEnabled, firmWare: atom.firmware)
} else {
trace("in getBluetoothTransmitter, case AtomType but cgmTransmitterDelegate is nil, looks like a coding error ", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .error)
}
}
case .DropletType:
if let droplet = bluetoothPeripheral as? Droplet {
@ -752,6 +794,11 @@ class BluetoothPeripheralManager: NSObject {
return .MiaoMiaoType
}
case .AtomType:
if bluetoothTransmitter is CGMAtomTransmitter {
return .AtomType
}
case .BluconType:
if bluetoothTransmitter is CGMBluconTransmitter {
return .BluconType
@ -838,6 +885,14 @@ class BluetoothPeripheralManager: NSObject {
return CGMMiaoMiaoTransmitter(address: nil, name: nil, bluetoothTransmitterDelegate: bluetoothTransmitterDelegate ?? self, cGMMiaoMiaoTransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, sensorSerialNumber: nil, webOOPEnabled: nil, nonFixedSlopeEnabled: nil)
case .AtomType:
guard let cgmTransmitterDelegate = cgmTransmitterDelegate else {
fatalError("in createNewTransmitter, AtomType, cgmTransmitterDelegate is nil")
}
return CGMAtomTransmitter(address: nil, name: nil, bluetoothTransmitterDelegate: bluetoothTransmitterDelegate ?? self, cGMAtomTransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, webOOPEnabled: nil, nonFixedSlopeEnabled: nil, firmWare: nil)
case .DropletType:
guard let cgmTransmitterDelegate = cgmTransmitterDelegate else {
@ -1117,7 +1172,7 @@ class BluetoothPeripheralManager: NSObject {
bluetoothPeripheral.blePeripheral.parameterUpdateNeededAtNextConnect = true
}
case .WatlaaType, .DexcomG5Type, .BubbleType, .MiaoMiaoType, .BluconType, .GNSentryType, .BlueReaderType, .DropletType, .DexcomG4Type, .DexcomG6Type, .Libre2Type:
case .WatlaaType, .DexcomG5Type, .BubbleType, .MiaoMiaoType, .BluconType, .GNSentryType, .BlueReaderType, .DropletType, .DexcomG4Type, .DexcomG6Type, .Libre2Type, .AtomType:
// nothing to check
break

View File

@ -433,7 +433,15 @@ class Trace {
traceInfo.appendStringAndNewLine(" batteryLevel : " + miaoMiao.batteryLevel.description)
}
case .AtomType:
if let miaoMiao = blePeripheral.atom {
traceInfo.appendStringAndNewLine(" type = " + bluetoothPeripheralType.rawValue)
traceInfo.appendStringAndNewLine(" batteryLevel : " + miaoMiao.batteryLevel.description)
}
case .WatlaaType:
if let watlaa = blePeripheral.watlaa {

View File

@ -0,0 +1,306 @@
import UIKit
class AtomBluetoothPeripheralViewModel {
// MARK: - private properties
/// settings specific for Atom
private enum Settings:Int, CaseIterable {
/// Libre sensor type
case sensorType = 0
/// Sensor serial number
case sensorSerialNumber = 1
/// sensor State
case sensorState = 2
/// battery level
case batteryLevel = 3
/// firmware version
case firmWare = 4
/// hardware version
case hardWare = 5
}
/// Atom settings willb be in section 0 + numberOfGeneralSections
private let sectionNumberForAtomSpecificSettings = 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 AtomBluetoothPeripheralViewModel - 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 atom: Atom? {
get {
return bluetoothPeripheral as? Atom
}
}
// 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 Atom = atom else {return}
guard let blueToothTransmitter = bluetoothPeripheralManager.getBluetoothTransmitter(for: Atom, createANewOneIfNecesssary: false) else {return}
guard let cGMAtomBluetoothTransmitter = blueToothTransmitter as? CGMAtomTransmitter else {return}
cGMAtomBluetoothTransmitter.cGMAtomTransmitterDelegate = bluetoothPeripheralManager as! BluetoothPeripheralManager
}
}
// MARK: - conform to BluetoothPeripheralViewModel
extension AtomBluetoothPeripheralViewModel: BluetoothPeripheralViewModel {
func configure(bluetoothPeripheral: BluetoothPeripheral?, bluetoothPeripheralManager: BluetoothPeripheralManaging, tableView: UITableView, bluetoothPeripheralViewController: BluetoothPeripheralViewController) {
self.bluetoothPeripheralManager = bluetoothPeripheralManager
self.tableView = tableView
self.bluetoothPeripheralViewController = bluetoothPeripheralViewController
self.bluetoothPeripheral = bluetoothPeripheral
if let bluetoothPeripheral = bluetoothPeripheral {
if let atom = bluetoothPeripheral as? Atom {
if let blueToothTransmitter = bluetoothPeripheralManager.getBluetoothTransmitter(for: atom, createANewOneIfNecesssary: false), let cGMAtomTransmitter = blueToothTransmitter as? CGMAtomTransmitter {
// set CGMAtomTransmitter delegate to self.
cGMAtomTransmitter.cGMAtomTransmitterDelegate = self
}
} else {
fatalError("in AtomBluetoothPeripheralViewModel, configure. bluetoothPeripheral is not Atom")
}
}
}
func screenTitle() -> String {
return BluetoothPeripheralType.AtomType.rawValue
}
func sectionTitle(forSection section: Int) -> String {
return BluetoothPeripheralType.AtomType.rawValue
}
func update(cell: UITableViewCell, forRow rawValue: Int, forSection section: Int, for bluetoothPeripheral: BluetoothPeripheral) {
// verify that bluetoothPeripheral is a Atom
guard let atom = bluetoothPeripheral as? Atom else {
fatalError("AtomBluetoothPeripheralViewModel update, bluetoothPeripheral is not Atom")
}
// default value for accessoryView is nil
cell.accessoryView = nil
guard let setting = Settings(rawValue: rawValue) else { fatalError("AtomBluetoothPeripheralViewModel update, unexpected setting") }
switch setting {
case .sensorType:
cell.accessoryType = .none
cell.textLabel?.text = Texts_BluetoothPeripheralView.sensorType
if let libreSensorType = atom.blePeripheral.libreSensorType {
cell.detailTextLabel?.text = libreSensorType.description
} else {
cell.detailTextLabel?.text = nil
}
case .sensorState:
cell.accessoryType = .none
cell.textLabel?.text = Texts_Common.sensorStatus
cell.detailTextLabel?.text = atom.sensorState.translatedDescription
case .batteryLevel:
cell.textLabel?.text = Texts_BluetoothPeripheralsView.batteryLevel
if atom.batteryLevel > 0 {
cell.detailTextLabel?.text = atom.batteryLevel.description + " %"
} else {
cell.detailTextLabel?.text = ""
}
cell.accessoryType = .none
case .firmWare:
cell.textLabel?.text = Texts_Common.firmware
cell.detailTextLabel?.text = atom.firmware
cell.accessoryType = .disclosureIndicator
case .hardWare:
cell.textLabel?.text = Texts_Common.hardware
cell.detailTextLabel?.text = atom.hardware
cell.accessoryType = .disclosureIndicator
case .sensorSerialNumber:
cell.textLabel?.text = Texts_BluetoothPeripheralView.sensorSerialNumber
cell.detailTextLabel?.text = atom.blePeripheral.sensorSerialNumber
cell.accessoryType = .disclosureIndicator
}
}
func userDidSelectRow(withSettingRawValue rawValue: Int, forSection section: Int, for bluetoothPeripheral: BluetoothPeripheral, bluetoothPeripheralManager: BluetoothPeripheralManaging) -> SettingsSelectedRowAction {
// verify that bluetoothPeripheral is a Atom
guard let atom = bluetoothPeripheral as? Atom else {
fatalError("AtomBluetoothPeripheralViewModel userDidSelectRow, bluetoothPeripheral is not Atom")
}
guard let setting = Settings(rawValue: rawValue) else { fatalError("AtomBluetoothPeripheralViewModel userDidSelectRow, unexpected setting") }
switch setting {
case .batteryLevel, .sensorType, .sensorState:
return .nothing
case .firmWare:
// firmware text could be longer than screen width, clicking the row allos to see it in pop up with more text place
if let firmware = atom.firmware {
return .showInfoText(title: Texts_HomeView.info, message: Texts_Common.firmware + " : " + firmware)
}
case .hardWare:
// hardware text could be longer than screen width, clicking the row allows to see it in pop up with more text place
if let hardware = atom.hardware {
return .showInfoText(title: Texts_HomeView.info, message: Texts_Common.hardware + " : " + hardware)
}
case .sensorSerialNumber:
// serial text could be longer than screen width, clicking the row allows to see it in a pop up with more text place
if let serialNumber = atom.blePeripheral.sensorSerialNumber {
return .showInfoText(title: Texts_HomeView.info, message: Texts_BluetoothPeripheralView.sensorSerialNumber + " : " + serialNumber)
}
}
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 CGMAtomTransmitterDelegate
extension AtomBluetoothPeripheralViewModel: CGMAtomTransmitterDelegate {
func received(libreSensorType: LibreSensorType, from cGMAtomTransmitter: CGMAtomTransmitter) {
// inform bluetoothPeripheralManager, bluetoothPeripheralManager will store the libreSensorType in the atom object
(bluetoothPeripheralManager as? CGMAtomTransmitterDelegate)?.received(libreSensorType: libreSensorType, from: cGMAtomTransmitter)
// here's the trigger to update the table row for sensorType
reloadRow(row: Settings.sensorType.rawValue)
}
func received(serialNumber: String, from cGMAtomTransmitter: CGMAtomTransmitter) {
// inform also bluetoothPeripheralManager
(bluetoothPeripheralManager as? CGMAtomTransmitterDelegate)?.received(serialNumber: serialNumber, from: cGMAtomTransmitter)
// here's the trigger to update the table
reloadRow(row: Settings.sensorSerialNumber.rawValue)
}
func received(batteryLevel: Int, from cGMAtomTransmitter: CGMAtomTransmitter) {
// inform also bluetoothPeripheralManager
(bluetoothPeripheralManager as? CGMAtomTransmitterDelegate)?.received(batteryLevel: batteryLevel, from: cGMAtomTransmitter)
// here's the trigger to update the table
reloadRow(row: Settings.batteryLevel.rawValue)
}
func received(sensorStatus: LibreSensorState, from cGMAtomTransmitter: CGMAtomTransmitter) {
// inform also bluetoothPeripheralManager
(bluetoothPeripheralManager as? CGMAtomTransmitterDelegate)?.received(sensorStatus: sensorStatus, from: cGMAtomTransmitter)
// here's the trigger to update the table
reloadRow(row: Settings.sensorState.rawValue)
}
func received(firmware: String, from cGMAtomTransmitter: CGMAtomTransmitter) {
// inform also bluetoothPeripheralManager
(bluetoothPeripheralManager as? CGMAtomTransmitterDelegate)?.received(firmware: firmware, from: cGMAtomTransmitter)
// here's the trigger to update the table
reloadRow(row: Settings.firmWare.rawValue)
}
func received(hardware: String, from cGMAtomTransmitter: CGMAtomTransmitter) {
// inform also bluetoothPeripheralManager
(bluetoothPeripheralManager as? CGMAtomTransmitterDelegate)?.received(hardware: hardware, from: cGMAtomTransmitter)
// here's the trigger to update the table
reloadRow(row: Settings.hardWare.rawValue)
}
private func reloadRow(row: Int) {
if let bluetoothPeripheralViewController = bluetoothPeripheralViewController {
tableView?.reloadRows(at: [IndexPath(row: row, section: bluetoothPeripheralViewController.numberOfGeneralSections() + sectionNumberForAtomSpecificSettings)], with: .none)
}
}
}

View File

@ -1122,7 +1122,7 @@ final class RootViewController: UIViewController {
return DexcomCalibrator()
case .miaomiao, .GNSentry, .Blucon, .Bubble, .Droplet1, .blueReader, .watlaa, .Libre2:
case .miaomiao, .GNSentry, .Blucon, .Bubble, .Droplet1, .blueReader, .watlaa, .Libre2, .Atom:
if cgmTransmitter.isWebOOPEnabled() {