resolve merge conflicts
This commit is contained in:
commit
fe2b988b7c
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
|
@ -61,6 +61,16 @@
|
|||
F8297F5A238EE14E00D74D66 /* TextsBluetoothPeripheralView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8297F58238EE14E00D74D66 /* TextsBluetoothPeripheralView.swift */; };
|
||||
F83098FE23AD3F84005741DF /* UITabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F83098FD23AD3F84005741DF /* UITabBarController.swift */; };
|
||||
F830990523B94ED7005741DF /* TimeScheduleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F830990423B94ED7005741DF /* TimeScheduleViewController.swift */; };
|
||||
F830991C23C2909E005741DF /* Watlaa+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = F830991A23C2909E005741DF /* Watlaa+CoreDataClass.swift */; };
|
||||
F830991D23C2909E005741DF /* Watlaa+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F830991B23C2909E005741DF /* Watlaa+CoreDataProperties.swift */; };
|
||||
F830992023C291E2005741DF /* WatlaaBluetoothTransmitterMaster.swift in Sources */ = {isa = PBXBuildFile; fileRef = F830991F23C291E2005741DF /* WatlaaBluetoothTransmitterMaster.swift */; };
|
||||
F830992323C291EE005741DF /* Watlaa+BluetoothPeripheral.swift in Sources */ = {isa = PBXBuildFile; fileRef = F830992223C291EE005741DF /* Watlaa+BluetoothPeripheral.swift */; };
|
||||
F830992623C32251005741DF /* WatlaaMasterBluetoothPeripheralViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F830992523C32251005741DF /* WatlaaMasterBluetoothPeripheralViewModel.swift */; };
|
||||
F830992823C32A13005741DF /* TextsWatlaaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F830992723C32A13005741DF /* TextsWatlaaView.swift */; };
|
||||
F830992A23C32A98005741DF /* WatlaaView.strings in Resources */ = {isa = PBXBuildFile; fileRef = F830992923C32A98005741DF /* WatlaaView.strings */; };
|
||||
F830992C23C694F4005741DF /* WatlaaAccessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F830992B23C694F4005741DF /* WatlaaAccessor.swift */; };
|
||||
F830992E23C7D756005741DF /* WatlaaBluetoothTransmitterMaster+CGMTransmitter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F830992D23C7D756005741DF /* WatlaaBluetoothTransmitterMaster+CGMTransmitter.swift */; };
|
||||
F830993023C928E0005741DF /* WatlaaBluetoothTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F830992F23C928E0005741DF /* WatlaaBluetoothTransmitterDelegate.swift */; };
|
||||
F856CE5B22EDC8E50083E436 /* ConstantsBluetoothPairing.swift in Sources */ = {isa = PBXBuildFile; fileRef = F856CE5A22EDC8E50083E436 /* ConstantsBluetoothPairing.swift */; };
|
||||
F85DC2ED21CFE2F500B9F74A /* BgReading+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F85DC2E721CFE2F500B9F74A /* BgReading+CoreDataProperties.swift */; };
|
||||
F85DC2EF21CFE2F500B9F74A /* Sensor+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F85DC2E921CFE2F500B9F74A /* Sensor+CoreDataProperties.swift */; };
|
||||
|
@ -180,6 +190,7 @@
|
|||
F8BECB05235CE5D80060DAE1 /* GlucoseChartManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8BECB04235CE5D80060DAE1 /* GlucoseChartManager.swift */; };
|
||||
F8BECB12235CEA9B0060DAE1 /* TimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8BECB11235CEA9B0060DAE1 /* TimeInterval.swift */; };
|
||||
F8C5EBE722F38F0E00563B5F /* Trace.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8C5EBE622F38F0E00563B5F /* Trace.swift */; };
|
||||
F8E3A2A323D4E7E200E5E98A /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F8E3A2A223D4E7E200E5E98A /* Default-568h@2x.png */; };
|
||||
F8E3C3AB21FE17B700907A04 /* StringProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E3C3AA21FE17B700907A04 /* StringProtocol.swift */; };
|
||||
F8E3C3AD21FE551C00907A04 /* DexcomCalibrator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E3C3AC21FE551C00907A04 /* DexcomCalibrator.swift */; };
|
||||
F8EA6C8221B723BC0082976B /* Date.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8EA6C8121B723BC0082976B /* Date.swift */; };
|
||||
|
@ -311,6 +322,17 @@
|
|||
F83098FD23AD3F84005741DF /* UITabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITabBarController.swift; sourceTree = "<group>"; };
|
||||
F830990323B3928E005741DF /* xdrip v8.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "xdrip v8.xcdatamodel"; sourceTree = "<group>"; };
|
||||
F830990423B94ED7005741DF /* TimeScheduleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeScheduleViewController.swift; sourceTree = "<group>"; };
|
||||
F830991523C28E79005741DF /* xdrip v9.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "xdrip v9.xcdatamodel"; sourceTree = "<group>"; };
|
||||
F830991A23C2909E005741DF /* Watlaa+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Watlaa+CoreDataClass.swift"; sourceTree = "<group>"; };
|
||||
F830991B23C2909E005741DF /* Watlaa+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Watlaa+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||
F830991F23C291E2005741DF /* WatlaaBluetoothTransmitterMaster.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WatlaaBluetoothTransmitterMaster.swift; sourceTree = "<group>"; };
|
||||
F830992223C291EE005741DF /* Watlaa+BluetoothPeripheral.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Watlaa+BluetoothPeripheral.swift"; sourceTree = "<group>"; };
|
||||
F830992523C32251005741DF /* WatlaaMasterBluetoothPeripheralViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatlaaMasterBluetoothPeripheralViewModel.swift; sourceTree = "<group>"; };
|
||||
F830992723C32A13005741DF /* TextsWatlaaView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextsWatlaaView.swift; sourceTree = "<group>"; };
|
||||
F830992923C32A98005741DF /* WatlaaView.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = WatlaaView.strings; sourceTree = "<group>"; };
|
||||
F830992B23C694F4005741DF /* WatlaaAccessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatlaaAccessor.swift; sourceTree = "<group>"; };
|
||||
F830992D23C7D756005741DF /* WatlaaBluetoothTransmitterMaster+CGMTransmitter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WatlaaBluetoothTransmitterMaster+CGMTransmitter.swift"; sourceTree = "<group>"; };
|
||||
F830992F23C928E0005741DF /* WatlaaBluetoothTransmitterDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatlaaBluetoothTransmitterDelegate.swift; sourceTree = "<group>"; };
|
||||
F846CDD523046BAC00DCF016 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/SettingsViews.strings"; sourceTree = "<group>"; };
|
||||
F846CDD623046BAE00DCF016 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/SettingsViews.strings; sourceTree = "<group>"; };
|
||||
F856CE5A22EDC8E50083E436 /* ConstantsBluetoothPairing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConstantsBluetoothPairing.swift; sourceTree = "<group>"; };
|
||||
|
@ -575,6 +597,7 @@
|
|||
F8C5EBE622F38F0E00563B5F /* Trace.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Trace.swift; sourceTree = "<group>"; };
|
||||
F8C5EBED22F5A52400563B5F /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Common.strings"; sourceTree = "<group>"; };
|
||||
F8C5EBEE22F5A52800563B5F /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/Common.strings; sourceTree = "<group>"; };
|
||||
F8E3A2A223D4E7E200E5E98A /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
|
||||
F8E3C3AA21FE17B700907A04 /* StringProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringProtocol.swift; sourceTree = "<group>"; };
|
||||
F8E3C3AC21FE551C00907A04 /* DexcomCalibrator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexcomCalibrator.swift; sourceTree = "<group>"; };
|
||||
F8EA6C8121B723BC0082976B /* Date.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Date.swift; sourceTree = "<group>"; };
|
||||
|
@ -883,6 +906,32 @@
|
|||
path = BluetoothPeripheralViewController;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F830991E23C291E2005741DF /* watlaa */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F830991F23C291E2005741DF /* WatlaaBluetoothTransmitterMaster.swift */,
|
||||
F830992D23C7D756005741DF /* WatlaaBluetoothTransmitterMaster+CGMTransmitter.swift */,
|
||||
F830992F23C928E0005741DF /* WatlaaBluetoothTransmitterDelegate.swift */,
|
||||
);
|
||||
path = watlaa;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F830992123C291EE005741DF /* watlaa */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F830992223C291EE005741DF /* Watlaa+BluetoothPeripheral.swift */,
|
||||
);
|
||||
path = watlaa;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F830992423C32226005741DF /* watlaa */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F830992523C32251005741DF /* WatlaaMasterBluetoothPeripheralViewModel.swift */,
|
||||
);
|
||||
path = watlaa;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F85DC29B21CFCEB800B9F74A /* Recovered References */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -926,6 +975,7 @@
|
|||
F8BDD457221DEF22006EAB84 /* SettingsViews.strings */,
|
||||
F8B48A9A22B2FA66009BCC01 /* SpeakReading.strings */,
|
||||
F869188F23A155100065B607 /* BluetoothPeripheralView.strings */,
|
||||
F830992923C32A98005741DF /* WatlaaView.strings */,
|
||||
);
|
||||
path = Storyboards;
|
||||
sourceTree = "<group>";
|
||||
|
@ -961,6 +1011,7 @@
|
|||
F8AC425121ADEBD60078C348 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F8E3A2A223D4E7E200E5E98A /* Default-568h@2x.png */,
|
||||
F8AC425B21ADEBD60078C348 /* Products */,
|
||||
F8AC425C21ADEBD60078C348 /* xdrip */,
|
||||
F85DC29B21CFCEB800B9F74A /* Recovered References */,
|
||||
|
@ -1065,6 +1116,7 @@
|
|||
F8B3A819227DEC92004BA588 /* README.md */,
|
||||
F8B3A815227DEC91004BA588 /* SensorsAccessor.swift */,
|
||||
F8F6226F233AA3B200BE8796 /* M5StackAccessor.swift */,
|
||||
F830992B23C694F4005741DF /* WatlaaAccessor.swift */,
|
||||
);
|
||||
path = accessors;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1178,6 +1230,7 @@
|
|||
F8BDD451221DEAB1006EAB84 /* TextsSettingsView.swift */,
|
||||
F8B48A9322B2A705009BCC01 /* TextsSpeakReading.swift */,
|
||||
F869188B23A044340065B607 /* TextsM5StackView.swift */,
|
||||
F830992723C32A13005741DF /* TextsWatlaaView.swift */,
|
||||
);
|
||||
path = Texts;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1243,6 +1296,8 @@
|
|||
F8EA6CA421B9A25B0082976B /* classes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F830991A23C2909E005741DF /* Watlaa+CoreDataClass.swift */,
|
||||
F830991B23C2909E005741DF /* Watlaa+CoreDataProperties.swift */,
|
||||
F8B3A79122635A25004BA588 /* AlertEntry+CoreDataClass.swift */,
|
||||
F8B3A79222635A25004BA588 /* AlertEntry+CoreDataProperties.swift */,
|
||||
F8B3A78C22622953004BA588 /* AlertType+CoreDataClass.swift */,
|
||||
|
@ -1274,6 +1329,7 @@
|
|||
F8F971AD23A5914C00C3F17D /* BluetoothPeripheral */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F830992123C291EE005741DF /* watlaa */,
|
||||
F8F971AE23A5914C00C3F17D /* CGM */,
|
||||
F8F971AF23A5914C00C3F17D /* M5 */,
|
||||
F8F971B323A5914C00C3F17D /* Generic */,
|
||||
|
@ -1326,6 +1382,7 @@
|
|||
F8F971B923A5915900C3F17D /* BluetoothTransmitter */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F830991E23C291E2005741DF /* watlaa */,
|
||||
F8F971BA23A5915900C3F17D /* CGM */,
|
||||
F8F971F523A5915900C3F17D /* M5Stack */,
|
||||
F8F971FF23A5915900C3F17D /* Generic */,
|
||||
|
@ -1500,10 +1557,10 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
F8F971F623A5915900C3F17D /* M5StackBluetoothTransmitter.swift */,
|
||||
F8F971FE23A5915900C3F17D /* M5StackBluetoothTransmitterDelegate.swift */,
|
||||
F8F971FB23A5915900C3F17D /* M5StackMessages */,
|
||||
F8F971F723A5915900C3F17D /* M5StackTransmitterOpCode.swift */,
|
||||
F8F971F823A5915900C3F17D /* Utilities */,
|
||||
F8F971FB23A5915900C3F17D /* M5StackMessages */,
|
||||
F8F971FE23A5915900C3F17D /* M5StackBluetoothTransmitterDelegate.swift */,
|
||||
);
|
||||
path = M5Stack;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1538,6 +1595,7 @@
|
|||
F8F9723623A5928D00C3F17D /* Models */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F830992423C32226005741DF /* watlaa */,
|
||||
F8F9723A23A5934300C3F17D /* M5StickC */,
|
||||
F8F9723723A5928D00C3F17D /* M5Stack */,
|
||||
);
|
||||
|
@ -1645,6 +1703,8 @@
|
|||
F869189023A155100065B607 /* BluetoothPeripheralView.strings in Resources */,
|
||||
F8BDD442221C9D0D006EAB84 /* Common.strings in Resources */,
|
||||
F8AC426A21ADEBD70078C348 /* LaunchScreen.storyboard in Resources */,
|
||||
F8E3A2A323D4E7E200E5E98A /* Default-568h@2x.png in Resources */,
|
||||
F830992A23C32A98005741DF /* WatlaaView.strings in Resources */,
|
||||
F8BDD438221A0349006EAB84 /* Localizable.strings in Resources */,
|
||||
F8B3A786225D4473004BA588 /* NightScoutTestResult.strings in Resources */,
|
||||
F8B48AA022B2FA7B009BCC01 /* HomeView.strings in Resources */,
|
||||
|
@ -1783,6 +1843,7 @@
|
|||
F8F9721223A5915900C3F17D /* FirmwareVersionTxMessage.swift in Sources */,
|
||||
F867E2612252ADAB000FD265 /* Calibration+CoreDataProperties.swift in Sources */,
|
||||
F8025E6B21F7CD7600ECF0C0 /* UIStoryboard.swift in Sources */,
|
||||
F830991D23C2909E005741DF /* Watlaa+CoreDataProperties.swift in Sources */,
|
||||
F8F9721623A5915900C3F17D /* CGMG4xDripTransmitter.swift in Sources */,
|
||||
F821CF8122A5C814005C1E43 /* RepeatingTimer.swift in Sources */,
|
||||
F8F9722223A5915900C3F17D /* CRC.swift in Sources */,
|
||||
|
@ -1802,6 +1863,7 @@
|
|||
F8B3A7B2226A0878004BA588 /* TextsAlerts.swift in Sources */,
|
||||
F8297F46238DC4AC00D74D66 /* BluetoothPeripheralManaging.swift in Sources */,
|
||||
F8F9721423A5915900C3F17D /* AuthChallengeRxMessage.swift in Sources */,
|
||||
F830992623C32251005741DF /* WatlaaMasterBluetoothPeripheralViewModel.swift in Sources */,
|
||||
F8025E5421EE8D2100ECF0C0 /* Libre1Calibrator.swift in Sources */,
|
||||
F81FA00A228F53680028C70F /* TextsHomeView.swift in Sources */,
|
||||
F8E3C3AD21FE551C00907A04 /* DexcomCalibrator.swift in Sources */,
|
||||
|
@ -1813,8 +1875,11 @@
|
|||
F8A1585522EDB706007F5B5D /* ConstantsCalibrationAlgorithms.swift in Sources */,
|
||||
F897AAF92200F2D200CDDD10 /* CBPeripheralState.swift in Sources */,
|
||||
F8F971B623A5914D00C3F17D /* M5Stack+BluetoothPeripheral.swift in Sources */,
|
||||
F830992323C291EE005741DF /* Watlaa+BluetoothPeripheral.swift in Sources */,
|
||||
F821CF57229BF43A005C1E43 /* SnoozeParameters.swift in Sources */,
|
||||
F830992823C32A13005741DF /* TextsWatlaaView.swift in Sources */,
|
||||
F8B3A79722635A25004BA588 /* AlertEntry+CoreDataProperties.swift in Sources */,
|
||||
F830992023C291E2005741DF /* WatlaaBluetoothTransmitterMaster.swift in Sources */,
|
||||
F8F971B723A5914D00C3F17D /* BluetoothPeripheralType.swift in Sources */,
|
||||
F80610C4222D4E4D00D8F236 /* ActionClosureable-extension.swift in Sources */,
|
||||
F8B3A835227F08AC004BA588 /* PickerViewController.swift in Sources */,
|
||||
|
@ -1836,6 +1901,7 @@
|
|||
F8F9722523A5915900C3F17D /* LibreRawGlucoseData.swift in Sources */,
|
||||
F8B3A830227F085A004BA588 /* SettingsTableViewCell.swift in Sources */,
|
||||
F8F62270233AA3B200BE8796 /* M5StackAccessor.swift in Sources */,
|
||||
F830991C23C2909E005741DF /* Watlaa+CoreDataClass.swift in Sources */,
|
||||
F8A1586122EDB844007F5B5D /* ConstantsNotifications.swift in Sources */,
|
||||
F8F9720423A5915900C3F17D /* TransmitterVersionTxMessage.swift in Sources */,
|
||||
F8F9720323A5915900C3F17D /* CGMG5Transmitter.swift in Sources */,
|
||||
|
@ -1867,6 +1933,7 @@
|
|||
F8A1586722EDB8BF007F5B5D /* ConstantsHomeView.swift in Sources */,
|
||||
F8A1585922EDB7C6007F5B5D /* ConstantsDefaultAlertLevels.swift in Sources */,
|
||||
F8A54AAD22D6859200934E7A /* SlopeParameters.swift in Sources */,
|
||||
F830993023C928E0005741DF /* WatlaaBluetoothTransmitterDelegate.swift in Sources */,
|
||||
F8B3A783225D37F2004BA588 /* TextsNightScoutTestResult.swift in Sources */,
|
||||
F8025C0A21D94FD700ECF0C0 /* CBManagerState.swift in Sources */,
|
||||
F8F9722723A5915900C3F17D /* CGMBluconTransmitter.swift in Sources */,
|
||||
|
@ -1874,6 +1941,7 @@
|
|||
F8F9721823A5915900C3F17D /* CGMBlueReaderTransmitter.swift in Sources */,
|
||||
F8A1586D22EDB9BE007F5B5D /* ConstantsDexcomFollower.swift in Sources */,
|
||||
F8F9720923A5915900C3F17D /* AESCrypt.m in Sources */,
|
||||
F830992E23C7D756005741DF /* WatlaaBluetoothTransmitterMaster+CGMTransmitter.swift in Sources */,
|
||||
F80ED2ED236F68F90005C035 /* SettingsViewM5StackGeneralSettingsViewModel.swift in Sources */,
|
||||
F8B3A850227F26F8004BA588 /* AlertTypesSettingsViewController.swift in Sources */,
|
||||
F8B3A808227A2933004BA588 /* SettingsSelectedRowAction.swift in Sources */,
|
||||
|
@ -1905,6 +1973,7 @@
|
|||
F8B3A84C227F090E004BA588 /* SettingsViewController.swift in Sources */,
|
||||
F8EEDD5222FECE3800D2D610 /* ConstantsLibreOOP.swift in Sources */,
|
||||
F8F9720B23A5915900C3F17D /* SensorDataRxMessage.swift in Sources */,
|
||||
F830992C23C694F4005741DF /* WatlaaAccessor.swift in Sources */,
|
||||
F8AC426021ADEBD60078C348 /* RootViewController.swift in Sources */,
|
||||
F8B3A78B225D473D004BA588 /* UIAlertController.swift in Sources */,
|
||||
F8F9720E23A5915900C3F17D /* AuthRequestRxMessage.swift in Sources */,
|
||||
|
@ -2430,6 +2499,7 @@
|
|||
F8AC429F21B31F160078C348 /* xdrip.xcdatamodeld */ = {
|
||||
isa = XCVersionGroup;
|
||||
children = (
|
||||
F830991523C28E79005741DF /* xdrip v9.xcdatamodel */,
|
||||
F830990323B3928E005741DF /* xdrip v8.xcdatamodel */,
|
||||
F8F9724523A699CE00C3F17D /* xdrip v7.xcdatamodel */,
|
||||
F8EBB030239701DA0058B0D4 /* xdrip v6.xcdatamodel */,
|
||||
|
@ -2439,7 +2509,7 @@
|
|||
F85C4A93233632EC00D6A86F /* xdrip v2.xcdatamodel */,
|
||||
F8AC42A021B31F160078C348 /* xdrip.xcdatamodel */,
|
||||
);
|
||||
currentVersion = F830990323B3928E005741DF /* xdrip v8.xcdatamodel */;
|
||||
currentVersion = F830991523C28E79005741DF /* xdrip v9.xcdatamodel */;
|
||||
path = xdrip.xcdatamodeld;
|
||||
sourceTree = "<group>";
|
||||
versionGroupType = wrapper.xcdatamodel;
|
||||
|
|
|
@ -6,6 +6,9 @@ enum BluetoothPeripheralCategory: String, CaseIterable {
|
|||
/// this is the category for M5Stack ad M5StickC
|
||||
case M5Stack = "M5Stack"
|
||||
|
||||
/// category for watlaa, master and follower
|
||||
case watlaa = "watlaa"
|
||||
|
||||
/// gets list of categories in array of strings, user will see those strings when selecting a category
|
||||
static func listOfCategories() -> [String] {
|
||||
|
||||
|
|
|
@ -13,6 +13,9 @@ enum BluetoothPeripheralType: String, CaseIterable {
|
|||
/// M5StickC
|
||||
case M5StickCType = "M5StickC"
|
||||
|
||||
/// watlaa master
|
||||
case watlaaMaster = "Watlaa master"
|
||||
|
||||
/// - returns: the BluetoothPeripheralViewModel
|
||||
func viewModel() -> BluetoothPeripheralViewModel {
|
||||
|
||||
|
@ -24,6 +27,8 @@ enum BluetoothPeripheralType: String, CaseIterable {
|
|||
case .M5StickCType:
|
||||
return M5StickCBluetoothPeripheralViewModel()
|
||||
|
||||
case .watlaaMaster:
|
||||
return WatlaaMasterBluetoothPeripheralViewModel()
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -47,6 +52,12 @@ enum BluetoothPeripheralType: String, CaseIterable {
|
|||
|
||||
return newM5StickC
|
||||
|
||||
case .watlaaMaster:
|
||||
|
||||
let newWatlaa = Watlaa(address: address, name: name, alias: nil, nsManagedObjectContext: nsManagedObjectContext)
|
||||
|
||||
return newWatlaa
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -61,6 +72,10 @@ enum BluetoothPeripheralType: String, CaseIterable {
|
|||
|
||||
case .M5StickCType:
|
||||
return .M5Stack
|
||||
|
||||
case .watlaaMaster:
|
||||
return .watlaa
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
import Foundation
|
||||
|
||||
extension Watlaa: BluetoothPeripheral {
|
||||
|
||||
func getDeviceName() -> String {
|
||||
return name
|
||||
}
|
||||
|
||||
func bluetoothPeripheralType() -> BluetoothPeripheralType {
|
||||
return .watlaaMaster
|
||||
}
|
||||
|
||||
func getAddress() -> String {
|
||||
return address
|
||||
}
|
||||
|
||||
func getAlias() -> String? {
|
||||
return alias
|
||||
}
|
||||
|
||||
func setAlias(_ value: String?) {
|
||||
alias = value
|
||||
}
|
||||
|
||||
func dontTryToConnectToThisBluetoothPeripheral() {
|
||||
shouldconnect = false
|
||||
}
|
||||
|
||||
func alwaysTryToConnectToThisBluetoothPeripheral() {
|
||||
shouldconnect = true
|
||||
}
|
||||
|
||||
func shouldXdripTryToConnectToThisBluetoothPeripheral() -> Bool {
|
||||
return shouldconnect
|
||||
}
|
||||
|
||||
func parameterUpdateNotNeededAtNextConnect() {
|
||||
parameterUpdateNeeded = false
|
||||
}
|
||||
|
||||
func parameterUpdateNeededAtNextConnect() {
|
||||
parameterUpdateNeeded = true
|
||||
}
|
||||
|
||||
func isParameterUpdateNeededAtNextConnect() -> Bool {
|
||||
return parameterUpdateNeeded
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -6,7 +6,7 @@ import CoreBluetooth
|
|||
/// Most of the functions are already defined by BlueToothTransmitter.swift - so most of these functions don't need re-implementation in CGMTransmitter classes that conform to this protocol.
|
||||
///
|
||||
/// An exception is for example initiatePairing, which is implemented in CGMG5Transmitter.swift, because that transmitter needs to send a message to the transmitter that will cause the app to request the user to accept the pairing
|
||||
protocol CGMTransmitter {
|
||||
protocol CGMTransmitter:AnyObject {
|
||||
|
||||
/// get device address, cgmtransmitters should also derive from BlueToothTransmitter, hence no need to implement this function
|
||||
///
|
||||
|
@ -85,6 +85,9 @@ enum CGMTransmitterType:String, CaseIterable {
|
|||
/// BlueReader
|
||||
case blueReader = "BlueReader"
|
||||
|
||||
/// watlaa
|
||||
case watlaa = "Watlaa (under development)"
|
||||
|
||||
/// does the transmitter need a transmitter id ?
|
||||
///
|
||||
/// can be used in UI stuff, if reset not possible then there's no need to show that option in the settings UI
|
||||
|
@ -112,6 +115,9 @@ enum CGMTransmitterType:String, CaseIterable {
|
|||
case .blueReader:
|
||||
return false
|
||||
|
||||
case .watlaa:
|
||||
return false
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,6 +151,8 @@ enum CGMTransmitterType:String, CaseIterable {
|
|||
case .blueReader:
|
||||
return false
|
||||
|
||||
case .watlaa:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -177,6 +185,10 @@ enum CGMTransmitterType:String, CaseIterable {
|
|||
|
||||
case .blueReader:
|
||||
return false
|
||||
|
||||
case .watlaa:
|
||||
return false
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -216,6 +228,8 @@ enum CGMTransmitterType:String, CaseIterable {
|
|||
case .blueReader:
|
||||
return nil
|
||||
|
||||
case .watlaa:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,6 +261,9 @@ enum CGMTransmitterType:String, CaseIterable {
|
|||
case .blueReader:
|
||||
return ConstantsDefaultAlertLevels.defaultBatteryAlertLevelBlueReader
|
||||
|
||||
case .watlaa:
|
||||
return ConstantsDefaultAlertLevels.defaultBatteryAlertLevelWatlaa
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,6 +295,9 @@ enum CGMTransmitterType:String, CaseIterable {
|
|||
case .blueReader:
|
||||
return false
|
||||
|
||||
case .watlaa:
|
||||
return false
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -306,6 +326,9 @@ enum CGMTransmitterType:String, CaseIterable {
|
|||
case .blueReader:
|
||||
return "%"
|
||||
|
||||
case .watlaa:
|
||||
return "%"
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,6 +357,9 @@ enum CGMTransmitterType:String, CaseIterable {
|
|||
case .blueReader:
|
||||
return false
|
||||
|
||||
case .watlaa:
|
||||
return false
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,10 @@ protocol CGMTransmitterDelegate:AnyObject {
|
|||
|
||||
/// to pass some text error message, delegate can decide to show to user, log, ...
|
||||
func error(message: String)
|
||||
|
||||
/// temporary function till all cgm transmitters have moved to bluetooth tab. - this function returns the currently assigned cgmTransmiter
|
||||
func getCGMTransmitter() -> CGMTransmitter?
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -25,9 +25,6 @@ class CGMBubbleTransmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
// used in parsing packet
|
||||
private var timeStampLastBgReading:Date
|
||||
|
||||
// counts number of times resend was requested due to crc error
|
||||
private var resendPacketCounter:Int = 0
|
||||
|
||||
/// used when processing Bubble data packet
|
||||
private var startDate:Date
|
||||
// receive buffer for bubble packets
|
||||
|
@ -241,7 +238,6 @@ class CGMBubbleTransmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
private func resetRxBuffer() {
|
||||
rxBuffer = Data()
|
||||
startDate = Date()
|
||||
resendPacketCounter = 0
|
||||
}
|
||||
|
||||
/// this transmitter supports oopWeb
|
||||
|
|
|
@ -98,9 +98,9 @@ class LibreDataParser {
|
|||
/// - completionHandler : will be called when glucose data is read with as parameter the timestamp of the last reading. Goal is that caller an set timeStampLastBgReading to the new value
|
||||
///
|
||||
/// parameter values that are not known, simply ignore them, if they are not known then they are probably not important, or they've already been passed to the delegate before.
|
||||
public static func libreDataProcessor(sensorSerialNumber: String?, webOOPEnabled: Bool, oopWebSite: String, oopWebToken: String, libreData: Data, cgmTransmitterDelegate : CGMTransmitterDelegate?, transmitterBatteryInfo:TransmitterBatteryInfo?, firmware: String?, hardware: String?, hardwareSerialNumber: String?, bootloader:String?, timeStampLastBgReading: Date, completionHandler:@escaping ((_ timeStampLastBgReading: Date) -> ())) {
|
||||
public static func libreDataProcessor(sensorSerialNumber: String?, webOOPEnabled: Bool, oopWebSite: String?, oopWebToken: String?, libreData: Data, cgmTransmitterDelegate : CGMTransmitterDelegate?, transmitterBatteryInfo:TransmitterBatteryInfo?, firmware: String?, hardware: String?, hardwareSerialNumber: String?, bootloader:String?, timeStampLastBgReading: Date, completionHandler:@escaping ((_ timeStampLastBgReading: Date) -> ())) {
|
||||
|
||||
if let sensorSerialNumber = sensorSerialNumber, webOOPEnabled {
|
||||
if let sensorSerialNumber = sensorSerialNumber, let oopWebSite = oopWebSite, let oopWebToken = oopWebToken, webOOPEnabled {
|
||||
LibreOOPClient.handleLibreData(libreData: libreData, timeStampLastBgReading: timeStampLastBgReading, serialNumber: sensorSerialNumber, oopWebSite: oopWebSite, oopWebToken: oopWebToken) {
|
||||
(result) in
|
||||
handleGlucoseData(result: result, cgmTransmitterDelegate: cgmTransmitterDelegate, transmitterBatteryInfo: transmitterBatteryInfo, firmware: firmware, hardware: hardware, hardwareSerialNumber: hardwareSerialNumber, bootloader: bootloader, sensorSerialNumber: sensorSerialNumber, completionHandler: completionHandler)
|
||||
|
|
|
@ -154,7 +154,7 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
|
|||
centralManager.cancelPeripheralConnection(peripheral)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// stops scanning
|
||||
|
@ -237,6 +237,11 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
|
|||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/// calls peripheral?.readValue(for: characteristic)
|
||||
func readValueForCharacteristic(for characteristic: CBCharacteristic) {
|
||||
peripheral?.readValue(for: characteristic)
|
||||
}
|
||||
|
||||
/// will write to characteristicToWriteTo
|
||||
/// - returns: true if writeValue was successfully called, doesn't necessarily mean data is successvully written to peripheral
|
||||
|
@ -357,6 +362,7 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
|
|||
}
|
||||
|
||||
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
|
||||
|
||||
timeStampLastStatusUpdate = Date()
|
||||
|
||||
trace("connected to peripheral with name %{public}@", log: log, category: ConstantsLog.categoryBlueToothTransmitter, type: .info, deviceName ?? "'unknown'")
|
||||
|
@ -369,6 +375,7 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
|
|||
}
|
||||
|
||||
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
|
||||
|
||||
timeStampLastStatusUpdate = Date()
|
||||
|
||||
if let error = error {
|
||||
|
@ -382,6 +389,7 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
|
|||
}
|
||||
|
||||
func centralManagerDidUpdateState(_ central: CBCentralManager) {
|
||||
|
||||
timeStampLastStatusUpdate = Date()
|
||||
|
||||
trace("in centralManagerDidUpdateState, for peripheral with name %{public}@, new state is %{public}@", log: log, category: ConstantsLog.categoryBlueToothTransmitter, type: .info, deviceName ?? "'unknown'", "\(central.state.toString())")
|
||||
|
@ -402,6 +410,7 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
|
|||
}
|
||||
|
||||
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
|
||||
|
||||
timeStampLastStatusUpdate = Date()
|
||||
|
||||
trace(" didDisconnect peripheral with name %{public}@", log: log, category: ConstantsLog.categoryBlueToothTransmitter, type: .info , deviceName ?? "'unknown'")
|
||||
|
@ -434,9 +443,11 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
|
|||
}
|
||||
|
||||
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
|
||||
|
||||
timeStampLastStatusUpdate = Date()
|
||||
|
||||
trace("didDiscoverServices for peripheral with name %{public}@", log: log, category: ConstantsLog.categoryBlueToothTransmitter, type: .info, deviceName ?? "'unknown'")
|
||||
|
||||
if let error = error {
|
||||
trace(" didDiscoverServices error: %{public}@", log: log, category: ConstantsLog.categoryBlueToothTransmitter, type: .error , "\(error.localizedDescription)")
|
||||
}
|
||||
|
@ -452,6 +463,7 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
|
|||
}
|
||||
|
||||
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
|
||||
|
||||
timeStampLastStatusUpdate = Date()
|
||||
|
||||
trace("didDiscoverCharacteristicsFor for peripheral with name %{public}@, for service with uuid %{public}@", log: log, category: ConstantsLog.categoryBlueToothTransmitter, type: .info, deviceName ?? "'unknown'", String(describing:service.uuid))
|
||||
|
@ -479,6 +491,7 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
|
|||
}
|
||||
|
||||
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
|
||||
|
||||
timeStampLastStatusUpdate = Date()
|
||||
|
||||
if let error = error {
|
||||
|
@ -489,6 +502,7 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
|
|||
}
|
||||
|
||||
func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
|
||||
|
||||
timeStampLastStatusUpdate = Date()
|
||||
|
||||
if let error = error {
|
||||
|
@ -498,6 +512,7 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
|
|||
}
|
||||
|
||||
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
|
||||
|
||||
timeStampLastStatusUpdate = Date()
|
||||
|
||||
if let error = error {
|
||||
|
|
|
@ -269,17 +269,6 @@ final class M5StackBluetoothTransmitter: BluetoothTransmitter {
|
|||
|
||||
// MARK: - overriden BluetoothTransmitter functions
|
||||
|
||||
override func centralManagerDidUpdateState(_ central: CBCentralManager) {
|
||||
|
||||
super.centralManagerDidUpdateState(central)
|
||||
|
||||
if deviceAddress == nil {
|
||||
/// this bluetoothTransmitter is created to start scanning for a new, unknown M5Stack, so start scanning
|
||||
_ = startScanning()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
|
||||
|
||||
super.centralManager(central, didDisconnectPeripheral: peripheral, error: error)
|
||||
|
@ -412,7 +401,6 @@ final class M5StackBluetoothTransmitter: BluetoothTransmitter {
|
|||
|
||||
trace(" value length should be minimum 2", log: log, category: ConstantsLog.categoryM5StackBluetoothTransmitter, type: .error)
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
let receivedBatteryLevel = Int(value[1])
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
import Foundation
|
||||
|
||||
protocol WatlaaBluetoothTransmitterDelegate: BluetoothTransmitterDelegate {
|
||||
|
||||
/// will be called if WatlaaBluetoothTransmitter is connected and ready to receive data, as soon as this is received, xdrip can request for example battery level
|
||||
func isReadyToReceiveData(watlaaBluetoothTransmitter: WatlaaBluetoothTransmitterMaster)
|
||||
|
||||
/// Watlaa is sending batteryLevel
|
||||
func receivedBattery(level: Int, watlaaBluetoothTransmitter: WatlaaBluetoothTransmitterMaster)
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
import Foundation
|
||||
|
||||
extension WatlaaBluetoothTransmitterMaster: CGMTransmitter {
|
||||
|
||||
func initiatePairing() {
|
||||
// no pairing needed for watlaa
|
||||
}
|
||||
|
||||
func reset(requested: Bool) {
|
||||
// no reset need for watlaa
|
||||
}
|
||||
|
||||
func setWebOOPEnabled(enabled: Bool) {
|
||||
// no web oop for watlaa as sensorid detection not supported
|
||||
}
|
||||
|
||||
func setWebOOPSiteAndToken(oopWebSite: String, oopWebToken: String) {
|
||||
// no web oop for watlaa as sensorid detection not supported
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,322 @@
|
|||
import Foundation
|
||||
import os
|
||||
import CoreBluetooth
|
||||
|
||||
final class WatlaaBluetoothTransmitterMaster: BluetoothTransmitter {
|
||||
|
||||
// MARK: UUID's
|
||||
|
||||
/// Glucose Data Service UUID
|
||||
let CBUUID_Data_Service = "00001010-1212-EFDE-0137-875F45AC0113"
|
||||
|
||||
/// Battery Service UUID
|
||||
let CBUUID_Battery_Service = "0000180F-0000-1000-8000-00805F9B34FB"
|
||||
|
||||
/// Current Time Service UUID
|
||||
let CBUUID_CurrentTime_Service = "00002A2B-0000-1000-8000-00805F9B34FB"
|
||||
|
||||
/// characteristic uuids (created them in an enum as there's a lot of them, it's easy to switch through the list)
|
||||
private enum CBUUID_Characteristic_UUID:String, CustomStringConvertible, CaseIterable {
|
||||
|
||||
/// Raw data characteristic
|
||||
case CBUUID_RawData_Characteristic = "00001011-1212-EFDE-0137-875F45AC0113"
|
||||
|
||||
/// Bridge connection status characteristic
|
||||
case CBUUID_BridgeConnectionStatus_Characteristic = "00001012-1212-EFDE-0137-875F45AC0113"
|
||||
|
||||
/// Last BG raw value characteristic
|
||||
case CBUUID_LastBGRawValue_Characteristic = "00001013-1212-EFDE-0137-875F45AC0113"
|
||||
|
||||
/// Calibration characteristic
|
||||
case CBUUID_Calibration_Characteristic = "00001014-1212-EFDE-0137-875F45AC0113"
|
||||
|
||||
/// Glucose unit characteristic
|
||||
case CBUUID_GlucoseUnit_Characteristic = "00001015-1212-EFDE-0137-875F45AC0113"
|
||||
|
||||
/// Alerts settings characteristic
|
||||
case CBUUID_AlertSettings_Characteristic = "00001016-1212-EFDE-0137-875F45AC0113"
|
||||
|
||||
/// Battery level characteristic
|
||||
case CBUUID_BatteryLevel_Characteristic = "00002A19-0000-1000-8000-00805F9B34FB"
|
||||
|
||||
/// Current time characteristic
|
||||
case CBUUID_CurrentTime_Characteristic = "00002A2B-0000-1000-8000-00805F9B34FB"
|
||||
|
||||
/// for logging, returns a readable name for the characteristic
|
||||
var description: String {
|
||||
switch self {
|
||||
|
||||
case .CBUUID_RawData_Characteristic:
|
||||
return "RawData"
|
||||
case .CBUUID_BridgeConnectionStatus_Characteristic:
|
||||
return "BridgeConnectionStatus"
|
||||
case .CBUUID_LastBGRawValue_Characteristic:
|
||||
return "LastBGRawValue"
|
||||
case .CBUUID_Calibration_Characteristic:
|
||||
return "Calibration"
|
||||
case .CBUUID_GlucoseUnit_Characteristic:
|
||||
return "GlucoseUnit"
|
||||
case .CBUUID_AlertSettings_Characteristic:
|
||||
return "AlertSettings"
|
||||
case .CBUUID_BatteryLevel_Characteristic:
|
||||
return "BatteryLevel"
|
||||
case .CBUUID_CurrentTime_Characteristic:
|
||||
return "CurrentTime"
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: Other private properties
|
||||
|
||||
/// for trace
|
||||
private let log = OSLog(subsystem: ConstantsLog.subSystem, category: ConstantsLog.categoryWatlaa)
|
||||
|
||||
/// will be used to pass back bluetooth and cgm related events
|
||||
private weak var cgmTransmitterDelegate:CGMTransmitterDelegate?
|
||||
|
||||
/// receive buffer for bubble packets
|
||||
private var rxBuffer:Data
|
||||
|
||||
/// used when processing Bubble data packet
|
||||
private var startDate:Date
|
||||
|
||||
// used in parsing packet
|
||||
private var timeStampLastBgReading:Date
|
||||
|
||||
/// battery level Characteristic, needed to be able to read value
|
||||
private var batteryLevelCharacteric: CBCharacteristic?
|
||||
|
||||
// MARK: - public functions
|
||||
|
||||
/// - 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
|
||||
init(address:String?, name: String?, cgmTransmitterDelegate:CGMTransmitterDelegate?, bluetoothTransmitterDelegate: WatlaaBluetoothTransmitterDelegate, bluetoothPeripheralType: BluetoothPeripheralType) {
|
||||
|
||||
// assign addressname and name or expected devicename
|
||||
var newAddressAndName:BluetoothTransmitter.DeviceAddressAndName = BluetoothTransmitter.DeviceAddressAndName.notYetConnected(expectedName: "watlaa")
|
||||
if let address = address {
|
||||
newAddressAndName = BluetoothTransmitter.DeviceAddressAndName.alreadyConnectedBefore(address: address, name: name)
|
||||
}
|
||||
|
||||
// initialize rxbuffer
|
||||
rxBuffer = Data()
|
||||
startDate = Date()
|
||||
|
||||
//assign CGMTransmitterDelegate
|
||||
self.cgmTransmitterDelegate = cgmTransmitterDelegate
|
||||
|
||||
//initialize timeStampLastBgReading
|
||||
timeStampLastBgReading = Date(timeIntervalSince1970: 0)
|
||||
|
||||
// initialize - CBUUID_Receive_Authentication.rawValue and CBUUID_Write_Control.rawValue will not be used in the superclass
|
||||
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: nil, servicesCBUUIDs: [CBUUID(string: CBUUID_Data_Service), CBUUID(string: CBUUID_Battery_Service), CBUUID(string: CBUUID_CurrentTime_Service)], CBUUID_ReceiveCharacteristic: CBUUID_Characteristic_UUID.CBUUID_RawData_Characteristic.rawValue, CBUUID_WriteCharacteristic: CBUUID_Characteristic_UUID.CBUUID_Calibration_Characteristic.rawValue, startScanningAfterInit: false, bluetoothTransmitterDelegate: bluetoothTransmitterDelegate)
|
||||
|
||||
}
|
||||
|
||||
/// read battery level
|
||||
public func readBatteryLevel() {
|
||||
|
||||
if let batteryLevelCharacteric = batteryLevelCharacteric {
|
||||
readValueForCharacteristic(for: batteryLevelCharacteric)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - private functions
|
||||
|
||||
/// reset rxBuffer, reset startDate, stop packetRxMonitorTimer, set resendPacketCounter to 0
|
||||
private func resetRxBuffer() {
|
||||
rxBuffer = Data()
|
||||
startDate = Date()
|
||||
}
|
||||
|
||||
/// creates CBUUID_Characteristic_UUID for the characteristicUUID
|
||||
private func receivedCharacteristicUUIDToCharacteristic(characteristicUUID:String) -> CBUUID_Characteristic_UUID? {
|
||||
|
||||
// using enum to make sure no new characteristics are forgotten in case new are added in the future
|
||||
for characteristic_UUID in CBUUID_Characteristic_UUID.allCases {
|
||||
|
||||
switch characteristic_UUID {
|
||||
|
||||
case .CBUUID_RawData_Characteristic:
|
||||
if CBUUID_Characteristic_UUID.CBUUID_RawData_Characteristic.rawValue.containsIgnoringCase(find: characteristicUUID) {
|
||||
return CBUUID_Characteristic_UUID.CBUUID_RawData_Characteristic
|
||||
}
|
||||
|
||||
case .CBUUID_BridgeConnectionStatus_Characteristic:
|
||||
if CBUUID_Characteristic_UUID.CBUUID_BridgeConnectionStatus_Characteristic.rawValue.containsIgnoringCase(find: characteristicUUID) {
|
||||
return CBUUID_Characteristic_UUID.CBUUID_BridgeConnectionStatus_Characteristic
|
||||
}
|
||||
|
||||
case .CBUUID_LastBGRawValue_Characteristic:
|
||||
if CBUUID_Characteristic_UUID.CBUUID_LastBGRawValue_Characteristic.rawValue.containsIgnoringCase(find: characteristicUUID) {
|
||||
return CBUUID_Characteristic_UUID.CBUUID_LastBGRawValue_Characteristic
|
||||
}
|
||||
|
||||
case .CBUUID_Calibration_Characteristic:
|
||||
if CBUUID_Characteristic_UUID.CBUUID_Calibration_Characteristic.rawValue.containsIgnoringCase(find: characteristicUUID) {
|
||||
return CBUUID_Characteristic_UUID.CBUUID_Calibration_Characteristic
|
||||
}
|
||||
|
||||
case .CBUUID_GlucoseUnit_Characteristic:
|
||||
if CBUUID_Characteristic_UUID.CBUUID_GlucoseUnit_Characteristic.rawValue.containsIgnoringCase(find: characteristicUUID) {
|
||||
return CBUUID_Characteristic_UUID.CBUUID_GlucoseUnit_Characteristic
|
||||
}
|
||||
|
||||
case .CBUUID_AlertSettings_Characteristic:
|
||||
if CBUUID_Characteristic_UUID.CBUUID_AlertSettings_Characteristic.rawValue.containsIgnoringCase(find: characteristicUUID) {
|
||||
return CBUUID_Characteristic_UUID.CBUUID_AlertSettings_Characteristic
|
||||
}
|
||||
|
||||
case .CBUUID_BatteryLevel_Characteristic:
|
||||
if CBUUID_Characteristic_UUID.CBUUID_BatteryLevel_Characteristic.rawValue.containsIgnoringCase(find: characteristicUUID) {
|
||||
return CBUUID_Characteristic_UUID.CBUUID_BatteryLevel_Characteristic
|
||||
}
|
||||
|
||||
case .CBUUID_CurrentTime_Characteristic:
|
||||
if CBUUID_Characteristic_UUID.CBUUID_CurrentTime_Characteristic.rawValue.containsIgnoringCase(find: characteristicUUID) {
|
||||
return CBUUID_Characteristic_UUID.CBUUID_CurrentTime_Characteristic
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
private func handleUpdateValueFor_RawData_Characteristic(value: Data) {
|
||||
|
||||
rxBuffer.append(value)
|
||||
|
||||
if rxBuffer.count >= 344 {
|
||||
|
||||
if (Crc.LibreCrc(data: &rxBuffer, headerOffset: 0)) {
|
||||
|
||||
// setting webOOPEnabled to false, as we don't have the sensor serial number
|
||||
LibreDataParser.libreDataProcessor(sensorSerialNumber: nil, webOOPEnabled: false, oopWebSite: nil, oopWebToken: nil, libreData: (rxBuffer.subdata(in: 0..<(344 + 0))), cgmTransmitterDelegate: cgmTransmitterDelegate, transmitterBatteryInfo: nil, firmware: nil, hardware: nil, hardwareSerialNumber: nil, bootloader: nil, timeStampLastBgReading: timeStampLastBgReading, completionHandler: {(timeStampLastBgReading:Date) in
|
||||
self.timeStampLastBgReading = timeStampLastBgReading
|
||||
|
||||
})
|
||||
|
||||
//reset the buffer
|
||||
resetRxBuffer()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private func handleUpdateValueFor_BridgeConnectionStatus_Characteristic(value: Data) {
|
||||
|
||||
}
|
||||
|
||||
private func handleUpdateValueFor_LastBGRawValue_Characteristic(value: Data) {
|
||||
|
||||
}
|
||||
|
||||
private func handleUpdateValueFor_Calibration_Characteristic(value: Data) {
|
||||
|
||||
}
|
||||
|
||||
private func handleUpdateValueFor_GlucoseUnit_Characteristic(value: Data) {
|
||||
|
||||
}
|
||||
|
||||
private func handleUpdateValueFor_AlertSettings_Characteristic(value: Data) {
|
||||
|
||||
}
|
||||
|
||||
private func handleUpdateValueFor_BatteryLevel_Characteristic(value: Data) {
|
||||
|
||||
guard value.count >= 1 else {
|
||||
trace(" value length should be minimum 1", log: log, category: ConstantsLog.categoryWatlaa, type: .error)
|
||||
return
|
||||
}
|
||||
|
||||
// Watlaa is sending batteryLevel, which is in the first byte
|
||||
let receivedBatteryLevel = Int(value[0])
|
||||
|
||||
(fixedBluetoothTransmitterDelegate as? WatlaaBluetoothTransmitterDelegate)?.receivedBattery(level: receivedBatteryLevel, watlaaBluetoothTransmitter: self)
|
||||
(variableBluetoothTransmitterDelegate as? WatlaaBluetoothTransmitterDelegate)?.receivedBattery(level: receivedBatteryLevel, watlaaBluetoothTransmitter: self)
|
||||
|
||||
}
|
||||
|
||||
private func handleUpdateValueFor_CurrentTime_Characteristic(value: Data) {
|
||||
|
||||
}
|
||||
|
||||
// MARK: - BluetoothTransmitter overriden functions
|
||||
|
||||
override func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
|
||||
|
||||
super.peripheral(peripheral, didDiscoverCharacteristicsFor: service, error: error)
|
||||
|
||||
//need to store some of the characteristics to be able to write to them
|
||||
if let characteristics = service.characteristics {
|
||||
for characteristic in characteristics {
|
||||
|
||||
if (characteristic.uuid == CBUUID(string: CBUUID_Characteristic_UUID.CBUUID_BatteryLevel_Characteristic.rawValue)) {
|
||||
trace(" found batteryLevelCharacteristic", log: log, category: ConstantsLog.categoryWatlaa, type: .info)
|
||||
batteryLevelCharacteric = characteristic
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// here all characteristics should be known, we can call isReadyToReceiveData
|
||||
(fixedBluetoothTransmitterDelegate as? WatlaaBluetoothTransmitterDelegate)?.isReadyToReceiveData(watlaaBluetoothTransmitter: self)
|
||||
(variableBluetoothTransmitterDelegate as? WatlaaBluetoothTransmitterDelegate)?.isReadyToReceiveData(watlaaBluetoothTransmitter: self)
|
||||
|
||||
}
|
||||
|
||||
override func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
|
||||
|
||||
super.peripheral(peripheral, didUpdateValueFor: characteristic, error: error)
|
||||
|
||||
// find the CBUUID_Characteristic_UUID
|
||||
guard let receivedCharacteristic = receivedCharacteristicUUIDToCharacteristic(characteristicUUID: characteristic.uuid.uuidString) else {
|
||||
trace("in peripheralDidUpdateValueFor, unknown characteristic received with uuid = %{public}@", log: log, category: ConstantsLog.categoryWatlaa, type: .error, characteristic.uuid.uuidString)
|
||||
return
|
||||
}
|
||||
|
||||
trace("in peripheralDidUpdateValueFor, characteristic uuid = %{public}@", log: log, category: ConstantsLog.categoryWatlaa, type: .info, receivedCharacteristic.description)
|
||||
|
||||
guard let value = characteristic.value else {return}
|
||||
|
||||
debuglogging("Received value from Watlaa : " + value.hexEncodedString())
|
||||
|
||||
switch receivedCharacteristic {
|
||||
|
||||
case .CBUUID_RawData_Characteristic:
|
||||
handleUpdateValueFor_RawData_Characteristic(value: value)
|
||||
|
||||
case .CBUUID_BridgeConnectionStatus_Characteristic:
|
||||
handleUpdateValueFor_BridgeConnectionStatus_Characteristic(value: value)
|
||||
|
||||
case .CBUUID_LastBGRawValue_Characteristic:
|
||||
handleUpdateValueFor_LastBGRawValue_Characteristic(value: value)
|
||||
|
||||
case .CBUUID_Calibration_Characteristic:
|
||||
handleUpdateValueFor_Calibration_Characteristic(value: value)
|
||||
|
||||
case .CBUUID_GlucoseUnit_Characteristic:
|
||||
handleUpdateValueFor_GlucoseUnit_Characteristic(value: value)
|
||||
|
||||
case .CBUUID_AlertSettings_Characteristic:
|
||||
handleUpdateValueFor_AlertSettings_Characteristic(value: value)
|
||||
|
||||
case .CBUUID_BatteryLevel_Characteristic:
|
||||
handleUpdateValueFor_BatteryLevel_Characteristic(value: value)
|
||||
|
||||
case .CBUUID_CurrentTime_Characteristic:
|
||||
handleUpdateValueFor_CurrentTime_Characteristic(value: value)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -9,6 +9,7 @@ enum ConstantsDefaultAlertLevels {
|
|||
static let defaultBatteryAlertLevelBlucon = 20
|
||||
static let defaultBatteryAlertLevelDroplet = 20
|
||||
static let defaultBatteryAlertLevelBlueReader = 20
|
||||
static let defaultBatteryAlertLevelWatlaa = 20
|
||||
|
||||
// blood glucose level alert values in mgdl
|
||||
static let veryHigh = 250
|
||||
|
|
|
@ -34,6 +34,9 @@ enum ConstantsLog {
|
|||
/// G5
|
||||
static let categoryCGMG5 = "CGMG5 "
|
||||
|
||||
/// watlaa
|
||||
static let categoryWatlaa = "Watlaa"
|
||||
|
||||
/// GNSEntry
|
||||
static let categoryCGMGNSEntry = "CGMGNSEntry "
|
||||
|
||||
|
@ -61,6 +64,9 @@ enum ConstantsLog {
|
|||
/// application data for M5Stack
|
||||
static let categoryApplicationDataM5Stacks = "ApplicationDataM5Stacks "
|
||||
|
||||
/// application data for M5Stack
|
||||
static let categoryApplicationDataWatlaa = "ApplicationDataWatlaa"
|
||||
|
||||
/// application for for M5StackName
|
||||
static let categoryApplicationDataM5StackNames = "ApplicationDataM5StackNames "
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
import Foundation
|
||||
import os
|
||||
import CoreData
|
||||
|
||||
class WatlaaAccessor {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
/// CoreDataManager to use
|
||||
private let coreDataManager:CoreDataManager
|
||||
|
||||
/// for logging
|
||||
private var log = OSLog(subsystem: ConstantsLog.subSystem, category: ConstantsLog.categoryApplicationDataWatlaa)
|
||||
|
||||
// MARK: - initializer
|
||||
|
||||
init(coreDataManager:CoreDataManager) {
|
||||
self.coreDataManager = coreDataManager
|
||||
}
|
||||
|
||||
// MARK: Public functions
|
||||
|
||||
/// gets all Watlaa instances from coredata
|
||||
func getWatlaas() -> [Watlaa] {
|
||||
|
||||
// create fetchRequest to get watlaa's as Watlaa classes
|
||||
let watlaaFetchRequest: NSFetchRequest<Watlaa> = Watlaa.fetchRequest()
|
||||
|
||||
// fetch the Watlaa's
|
||||
var watlaaArray = [Watlaa]()
|
||||
coreDataManager.mainManagedObjectContext.performAndWait {
|
||||
do {
|
||||
// Execute Fetch Request
|
||||
watlaaArray = try watlaaFetchRequest.execute()
|
||||
} catch {
|
||||
let fetchError = error as NSError
|
||||
trace("in getWatlaas, Unable to Execute Watlaas Fetch Request : %{public}@", log: self.log, category: ConstantsLog.categoryWatlaa, type: .error, fetchError.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
return watlaaArray
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -42,6 +42,9 @@ public class M5Stack: NSManagedObject {
|
|||
// this is creation of an M5Stack, not M5Stick, set isM5StickC to false
|
||||
self.isM5StickC = false
|
||||
|
||||
// by default, don't connect to WiFi
|
||||
self.connectToWiFi = false
|
||||
|
||||
}
|
||||
|
||||
private override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?) {
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
import Foundation
|
||||
import CoreData
|
||||
|
||||
public class Watlaa: NSManagedObject {
|
||||
|
||||
/// explanation, see function parameterUpdateNotNeededAtNextConnect in protocol BluetoothPeripheral
|
||||
public var parameterUpdateNeeded: Bool = false
|
||||
|
||||
/// battery level , not stored in coredata,
|
||||
public var batteryLevel: Int?
|
||||
|
||||
/// create Watlaa, shouldconnect default value = true
|
||||
/// - parameters:
|
||||
/// - rotation is internally stored as Int32, actual value should always be between 0 and 360 so UInt16 as parameter is sufficient.
|
||||
init(address: String, name: String, alias: String?, nsManagedObjectContext:NSManagedObjectContext) {
|
||||
|
||||
let entity = NSEntityDescription.entity(forEntityName: "Watlaa", in: nsManagedObjectContext)!
|
||||
|
||||
super.init(entity: entity, insertInto: nsManagedObjectContext)
|
||||
|
||||
self.address = address
|
||||
self.name = name
|
||||
self.shouldconnect = true
|
||||
self.alias = alias
|
||||
|
||||
}
|
||||
|
||||
private override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?) {
|
||||
super.init(entity: entity, insertInto: context)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import Foundation
|
||||
import CoreData
|
||||
|
||||
|
||||
extension Watlaa {
|
||||
|
||||
@nonobjc public class func fetchRequest() -> NSFetchRequest<Watlaa> {
|
||||
return NSFetchRequest<Watlaa>(entityName: "Watlaa")
|
||||
}
|
||||
|
||||
@NSManaged public var address: String
|
||||
@NSManaged public var name: String
|
||||
@NSManaged public var shouldconnect: Bool
|
||||
@NSManaged public var alias: String?
|
||||
|
||||
}
|
|
@ -3,6 +3,6 @@
|
|||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>_XCCurrentVersionName</key>
|
||||
<string>xdrip v8.xcdatamodel</string>
|
||||
<string>xdrip v9.xcdatamodel</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="15702" systemVersion="19C57" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<entity name="AlertEntry" representedClassName=".AlertEntry" syncable="YES">
|
||||
<attribute name="alertkind" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="start" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="value" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="alertType" maxCount="1" deletionRule="No Action" destinationEntity="AlertType" inverseName="alertEntries" inverseEntity="AlertType"/>
|
||||
</entity>
|
||||
<entity name="AlertType" representedClassName=".AlertType" syncable="YES">
|
||||
<attribute name="enabled" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="name" attributeType="String"/>
|
||||
<attribute name="overridemute" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="snooze" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="snoozeperiod" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="soundname" optional="YES" attributeType="String"/>
|
||||
<attribute name="vibrate" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<relationship name="alertEntries" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="AlertEntry" inverseName="alertType" inverseEntity="AlertEntry"/>
|
||||
</entity>
|
||||
<entity name="BgReading" representedClassName=".BgReading" syncable="YES">
|
||||
<attribute name="a" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="ageAdjustedRawValue" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="b" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="c" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="calculatedValue" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="calculatedValueSlope" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="calibrationFlag" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="deviceName" optional="YES" attributeType="String"/>
|
||||
<attribute name="filteredCalculatedValue" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="filteredData" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="hideSlope" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="id" attributeType="String"/>
|
||||
<attribute name="ra" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="rawData" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="rb" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="rc" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="timeStamp" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<relationship name="calibration" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Calibration" inverseName="bgreadings" inverseEntity="Calibration"/>
|
||||
<relationship name="sensor" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Sensor" inverseName="readings" inverseEntity="Sensor"/>
|
||||
</entity>
|
||||
<entity name="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="M5Stack" representedClassName=".M5Stack" syncable="YES">
|
||||
<attribute name="address" attributeType="String"/>
|
||||
<attribute name="alias" optional="YES" attributeType="String"/>
|
||||
<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="name" attributeType="String"/>
|
||||
<attribute name="rotation" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="shouldconnect" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="textcolor" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
</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"/>
|
||||
<relationship name="calibrations" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Calibration" inverseName="sensor" inverseEntity="Calibration"/>
|
||||
<relationship name="readings" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="BgReading" inverseName="sensor" inverseEntity="BgReading"/>
|
||||
</entity>
|
||||
<entity name="Watlaa" representedClassName=".Watlaa" syncable="YES">
|
||||
<attribute name="address" attributeType="String"/>
|
||||
<attribute name="alias" optional="YES" attributeType="String"/>
|
||||
<attribute name="name" attributeType="String"/>
|
||||
<attribute name="shouldconnect" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
</entity>
|
||||
<elements>
|
||||
<element name="AlertEntry" positionX="-648" positionY="189" width="128" height="105"/>
|
||||
<element name="AlertType" positionX="-657" positionY="180" width="128" height="165"/>
|
||||
<element name="BgReading" positionX="-285.87109375" positionY="31.9921875" width="128" height="330"/>
|
||||
<element name="Calibration" positionX="-859.21484375" positionY="46.21484375" width="128" height="285"/>
|
||||
<element name="M5Stack" positionX="-657" positionY="180" width="128" height="208"/>
|
||||
<element name="Sensor" positionX="-603.0859375" positionY="482.2890625" width="128" height="120"/>
|
||||
<element name="Watlaa" positionX="-639" positionY="207" width="128" height="103"/>
|
||||
</elements>
|
||||
</model>
|
|
@ -28,6 +28,9 @@ class BluetoothPeripheralManager: NSObject {
|
|||
/// reference to BgReadingsAccessor
|
||||
private var bgReadingsAccessor: BgReadingsAccessor
|
||||
|
||||
/// reference to watlaaAccessor
|
||||
private var watlaaAccessor: WatlaaAccessor
|
||||
|
||||
/// if scan is called, and a connection is successfully made to a new device, then a new M5Stack must be created, and this function will be called. It is owned by the UIViewController that calls the scan function
|
||||
private var callBackAfterDiscoveringDevice: ((BluetoothPeripheral) -> Void)?
|
||||
|
||||
|
@ -36,45 +39,102 @@ class BluetoothPeripheralManager: NSObject {
|
|||
|
||||
/// to solve problem that sometemes UserDefaults key value changes is triggered twice for just one change
|
||||
private let keyValueObserverTimeKeeper:KeyValueObserverTimeKeeper = KeyValueObserverTimeKeeper()
|
||||
|
||||
/// will be used to pass back bluetooth and cgm related events, probably temporary ?
|
||||
private(set) weak var cgmTransmitterDelegate:CGMTransmitterDelegate?
|
||||
|
||||
/// when xdrip connects to a BluetoothTransmitter that is also CGMTransmitter, then we'll call this function with the BluetoothTransmitter as argument. This is to let the cgmTransmitterDelegate know what is the CGMTransmitter
|
||||
private var onCGMTransmitterCreation: (CGMTransmitter?) -> ()
|
||||
|
||||
// MARK: - initializer
|
||||
|
||||
init(coreDataManager: CoreDataManager) {
|
||||
/// - parameters:
|
||||
/// - onCGMTransmitterCreation : to be called when cgmtransmitter is created
|
||||
init(coreDataManager: CoreDataManager, cgmTransmitterDelegate: CGMTransmitterDelegate, onCGMTransmitterCreation: @escaping (CGMTransmitter?) -> ()) {
|
||||
|
||||
// initialize properties
|
||||
self.coreDataManager = coreDataManager
|
||||
self.m5StackAccessor = M5StackAccessor(coreDataManager: coreDataManager)
|
||||
self.bgReadingsAccessor = BgReadingsAccessor(coreDataManager: coreDataManager)
|
||||
self.watlaaAccessor = WatlaaAccessor(coreDataManager: coreDataManager)
|
||||
self.cgmTransmitterDelegate = cgmTransmitterDelegate
|
||||
self.onCGMTransmitterCreation = onCGMTransmitterCreation
|
||||
|
||||
super.init()
|
||||
|
||||
// initialize m5Stacks
|
||||
let m5Stacks = m5StackAccessor.getM5Stacks()
|
||||
for m5Stack in m5Stacks {
|
||||
// need to initialize all types of bluetoothperipheral
|
||||
// using enum here to make sure future types are not forgotten
|
||||
for bluetoothPeripheralType in BluetoothPeripheralType.allCases {
|
||||
|
||||
// add it to the list of bluetoothPeripherals
|
||||
bluetoothPeripherals.append(m5Stack)
|
||||
|
||||
if m5Stack.shouldconnect {
|
||||
switch bluetoothPeripheralType {
|
||||
|
||||
case .M5StickCType:
|
||||
// no seperate handling needed for M5StickC because M5StickC is stored in coredata as M5Stack objecct, so it will be handled when going through case M5StackType
|
||||
break
|
||||
|
||||
// create an instance of M5StackBluetoothTransmitter, M5StackBluetoothTransmitter will automatically try to connect to the M5Stack with the address that is stored in m5Stack
|
||||
// add it to the array of bluetoothTransmitters
|
||||
bluetoothTransmitters.append(M5StackBluetoothTransmitter(address: m5Stack.address, name: m5Stack.name, delegate: self, blePassword: m5Stack.blepassword, bluetoothPeripheralType: m5Stack.isM5StickC ? .M5StickCType : .M5StackType))
|
||||
case .M5StackType:
|
||||
|
||||
} else {
|
||||
// initialize m5Stacks
|
||||
let m5Stacks = m5StackAccessor.getM5Stacks()
|
||||
for m5Stack in m5Stacks {
|
||||
|
||||
// add it to the list of bluetoothPeripherals
|
||||
bluetoothPeripherals.append(m5Stack)
|
||||
|
||||
if m5Stack.shouldconnect {
|
||||
|
||||
// create an instance of M5StackBluetoothTransmitter, M5StackBluetoothTransmitter will automatically try to connect to the M5Stack with the address that is stored in m5Stack
|
||||
// add it to the array of bluetoothTransmitters
|
||||
bluetoothTransmitters.append(M5StackBluetoothTransmitter(address: m5Stack.address, name: m5Stack.name, delegate: self, blePassword: m5Stack.blepassword, bluetoothPeripheralType: m5Stack.isM5StickC ? .M5StickCType : .M5StackType))
|
||||
|
||||
} else {
|
||||
|
||||
// shouldn't connect, so don't create an instance of M5StackBluetoothTransmitter
|
||||
// but append a nil element
|
||||
bluetoothTransmitters.append(nil)
|
||||
|
||||
}
|
||||
|
||||
// each time the app launches, we will send the parameters to all BluetoothPeripherals
|
||||
m5Stack.parameterUpdateNeededAtNextConnect()
|
||||
|
||||
}
|
||||
|
||||
// shouldn't connect, so don't create an instance of M5StackBluetoothTransmitter
|
||||
// but append a nil element
|
||||
bluetoothTransmitters.append(nil)
|
||||
|
||||
|
||||
case .watlaaMaster:
|
||||
|
||||
// initialize watlaa's
|
||||
let watlaas = watlaaAccessor.getWatlaas()
|
||||
for watlaa in watlaas {
|
||||
|
||||
// add it to the list of bluetoothPeripherals
|
||||
bluetoothPeripherals.append(watlaa)
|
||||
|
||||
if watlaa.shouldconnect {
|
||||
|
||||
// create an instance of WatlaaBluetoothTransmitter, WatlaaBluetoothTransmitter will automatically try to connect to the watlaa with the address that is stored in watlaa
|
||||
// add it to the array of bluetoothTransmitters
|
||||
bluetoothTransmitters.append(WatlaaBluetoothTransmitterMaster(address: watlaa.address, name: watlaa.name, cgmTransmitterDelegate: cgmTransmitterDelegate, bluetoothTransmitterDelegate: self, bluetoothPeripheralType: .watlaaMaster))
|
||||
|
||||
} else {
|
||||
|
||||
// shouldn't connect, so don't create an instance of M5StackBluetoothTransmitter
|
||||
// but append a nil element
|
||||
bluetoothTransmitters.append(nil)
|
||||
|
||||
}
|
||||
|
||||
// each time the app launches, we will send the parameters to all BluetoothPeripherals
|
||||
watlaa.parameterUpdateNeededAtNextConnect()
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// each time the app launches, we will send the parameters to all BluetoothPeripherals
|
||||
m5Stack.parameterUpdateNeededAtNextConnect()
|
||||
|
||||
}
|
||||
|
||||
// when user changes M5Stack related settings, then the transmitter need to get that info
|
||||
// when user changes any of the buetooth peripheral related settings, that need to be sent to the transmitter
|
||||
addObservers()
|
||||
|
||||
}
|
||||
|
@ -120,6 +180,10 @@ class BluetoothPeripheralManager: NSObject {
|
|||
_ = m5StackBluetoothTransmitter.writeBgReadingInfo(bgReading: bgReadingToSend[0])
|
||||
}
|
||||
|
||||
case .watlaaMaster:
|
||||
// no need to send reading to watlaa in master mode
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -129,6 +193,22 @@ class BluetoothPeripheralManager: NSObject {
|
|||
|
||||
// MARK: - private functions
|
||||
|
||||
/// check if transmitter in bluetoothTransmitters with index, is the cgmtransmitter currently assigned to delegate, if so set cgmtransmitter at delegate to nil - This should be temporary till cgm transmitters have moved to bluetooth tab
|
||||
private func setCGMTransmitterToNilAtDelegate(withIndexInBluetoothTransmitters index: Int) {
|
||||
|
||||
if let cgmTransmitter = cgmTransmitterDelegate?.getCGMTransmitter() as? BluetoothTransmitter, let transmitterBeingDeleted = bluetoothTransmitters[index] {
|
||||
|
||||
if cgmTransmitter.getAddress() == transmitterBeingDeleted.getAddress() {
|
||||
|
||||
// so the cgmTransmitter is actually being deleted, so we need to also assign cgmTransmitterDelegate to nil to make sure there's no more reference to it
|
||||
onCGMTransmitterCreation(nil)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// when user changes M5Stack related settings, then the transmitter need to get that info, add observers
|
||||
private func addObservers() {
|
||||
|
||||
|
@ -143,7 +223,6 @@ class BluetoothPeripheralManager: NSObject {
|
|||
UserDefaults.standard.addObserver(self, forKeyPath: UserDefaults.Key.nightScoutUrl.rawValue, options: .new, context: nil)
|
||||
UserDefaults.standard.addObserver(self, forKeyPath: UserDefaults.Key.nightScoutAPIKey.rawValue, options: .new, context: nil)
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// disconnect from bluetoothPeripheral - and don't reconnect - set shouldconnect to false
|
||||
|
@ -157,7 +236,7 @@ class BluetoothPeripheralManager: NSObject {
|
|||
|
||||
if let bluetoothTransmitter = getBluetoothTransmitter(for: bluetoothPeripheral, createANewOneIfNecesssary: false) {
|
||||
|
||||
bluetoothTransmitter.disconnect(reconnectAfterDisconnect: false)
|
||||
_ = bluetoothTransmitter.disconnect(reconnectAfterDisconnect: false)
|
||||
|
||||
}
|
||||
|
||||
|
@ -175,6 +254,10 @@ class BluetoothPeripheralManager: NSObject {
|
|||
|
||||
return M5StackBluetoothTransmitter(address: nil, name: nil, delegate: self, blePassword: UserDefaults.standard.m5StackBlePassword, bluetoothPeripheralType: type)
|
||||
|
||||
case .watlaaMaster:
|
||||
|
||||
return WatlaaBluetoothTransmitterMaster(address: nil, name: nil, cgmTransmitterDelegate: cgmTransmitterDelegate, bluetoothTransmitterDelegate: self, bluetoothPeripheralType: type)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -192,6 +275,12 @@ class BluetoothPeripheralManager: NSObject {
|
|||
return bluetoothTransmitter.bluetoothPeripheralType
|
||||
}
|
||||
|
||||
case .watlaaMaster:
|
||||
|
||||
if bluetoothTransmitter is WatlaaBluetoothTransmitterMaster {
|
||||
return .watlaaMaster
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -297,6 +386,9 @@ class BluetoothPeripheralManager: NSObject {
|
|||
if !success {
|
||||
bluetoothPeripheral.parameterUpdateNeededAtNextConnect()
|
||||
}
|
||||
|
||||
case .watlaaMaster:
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
|
@ -306,9 +398,7 @@ class BluetoothPeripheralManager: NSObject {
|
|||
|
||||
}
|
||||
|
||||
// MARK: - extensions
|
||||
|
||||
// MARK: extension BluetoothPeripheralManaging
|
||||
// MARK: - conform to BluetoothPeripheralManaging
|
||||
|
||||
extension BluetoothPeripheralManager: BluetoothPeripheralManaging {
|
||||
|
||||
|
@ -404,6 +494,14 @@ extension BluetoothPeripheralManager: BluetoothPeripheralManaging {
|
|||
newTransmitter = M5StackBluetoothTransmitter(address: m5Stack.address, name: m5Stack.name, delegate: self, blePassword: blePassword, bluetoothPeripheralType: bluetoothPeripheral.bluetoothPeripheralType())
|
||||
}
|
||||
|
||||
case .watlaaMaster:
|
||||
|
||||
if let watlaa = bluetoothPeripheral as? Watlaa {
|
||||
|
||||
newTransmitter = WatlaaBluetoothTransmitterMaster(address: watlaa.address, name: watlaa.name, cgmTransmitterDelegate: cgmTransmitterDelegate, bluetoothTransmitterDelegate: self, bluetoothPeripheralType: .watlaaMaster)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bluetoothTransmitters[index] = newTransmitter
|
||||
|
@ -426,6 +524,9 @@ extension BluetoothPeripheralManager: BluetoothPeripheralManaging {
|
|||
return
|
||||
}
|
||||
|
||||
// check if transmitter being deleted is assigned to cgmTransmitterDelegate, if so we need to set it also to nil, otherwise the bluetoothTransmitter deinit function wouldn't get called
|
||||
setCGMTransmitterToNilAtDelegate(withIndexInBluetoothTransmitters: index)
|
||||
|
||||
// set bluetoothTransmitter to nil, this will also initiate a disconnect
|
||||
bluetoothTransmitters[index] = nil
|
||||
|
||||
|
@ -468,6 +569,9 @@ extension BluetoothPeripheralManager: BluetoothPeripheralManaging {
|
|||
|
||||
if let index = firstIndexInBluetoothPeripherals(bluetoothPeripheral: bluetoothPeripheral) {
|
||||
|
||||
// check if transmitter being deleted is assigned to cgmTransmitterDelegate, if so we need to set it also to nil, otherwise the bluetoothTransmitter deinit function wouldn't get called
|
||||
setCGMTransmitterToNilAtDelegate(withIndexInBluetoothTransmitters: index)
|
||||
|
||||
bluetoothTransmitters[index] = nil
|
||||
|
||||
}
|
||||
|
@ -475,12 +579,17 @@ extension BluetoothPeripheralManager: BluetoothPeripheralManaging {
|
|||
|
||||
}
|
||||
|
||||
// MARK: extension M5StackBluetoothDelegate
|
||||
// MARK: - conform to BluetoothTransmitterDelegate
|
||||
|
||||
extension BluetoothPeripheralManager: BluetoothTransmitterDelegate {
|
||||
|
||||
func didConnectTo(bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
// temporary, till all cgm's are moved to second tab
|
||||
if bluetoothTransmitter is CGMTransmitter {
|
||||
onCGMTransmitterCreation((bluetoothTransmitter as! CGMTransmitter))
|
||||
}
|
||||
|
||||
// if tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral is nil, then this is a connection to an already known/stored BluetoothTransmitter. BluetoothPeripheralManager is not interested in this info.
|
||||
guard let tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral = tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral else {
|
||||
trace("in didConnect, tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral is nil, no further processing", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info)
|
||||
|
@ -530,10 +639,18 @@ extension BluetoothPeripheralManager: BluetoothTransmitterDelegate {
|
|||
self.callBackAfterDiscoveringDevice = nil
|
||||
}
|
||||
|
||||
// assign tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral to nil here
|
||||
self.tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral = nil
|
||||
}
|
||||
|
||||
func deviceDidUpdateBluetoothState(state: CBManagerState, bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
trace("in deviceDidUpdateBluetoothState, no further action", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info)
|
||||
|
||||
if bluetoothTransmitter.deviceAddress == nil {
|
||||
/// this bluetoothTransmitter is created to start scanning for a new, unknown M5Stack, so start scanning
|
||||
_ = bluetoothTransmitter.startScanning()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -549,7 +666,28 @@ extension BluetoothPeripheralManager: BluetoothTransmitterDelegate {
|
|||
|
||||
}
|
||||
|
||||
// MARK: conform to M5StackBluetoothTransmitterDelegate
|
||||
// MARK: - conform to WatlaaBluetoothTransmitterDelegate
|
||||
|
||||
extension BluetoothPeripheralManager: WatlaaBluetoothTransmitterDelegate {
|
||||
|
||||
func isReadyToReceiveData(watlaaBluetoothTransmitter: WatlaaBluetoothTransmitterMaster) {
|
||||
|
||||
// request battery level
|
||||
watlaaBluetoothTransmitter.readBatteryLevel()
|
||||
|
||||
}
|
||||
|
||||
func receivedBattery(level: Int, watlaaBluetoothTransmitter: WatlaaBluetoothTransmitterMaster) {
|
||||
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: watlaaBluetoothTransmitter), let watlaa = bluetoothPeripherals[index] as? Watlaa else {return}
|
||||
|
||||
watlaa.batteryLevel = level
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - conform to M5StackBluetoothTransmitterDelegate
|
||||
|
||||
extension BluetoothPeripheralManager: M5StackBluetoothTransmitterDelegate {
|
||||
|
||||
|
@ -636,7 +774,7 @@ extension BluetoothPeripheralManager: M5StackBluetoothTransmitterDelegate {
|
|||
|
||||
}
|
||||
|
||||
/// bluetoothPeripheral is asking for an update of all parameters, send them
|
||||
/// M5Stack is asking for an update of all parameters, send them
|
||||
func isAskingForAllParameters(m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: m5StackBluetoothTransmitter) else {
|
||||
|
@ -675,7 +813,7 @@ extension BluetoothPeripheralManager: M5StackBluetoothTransmitterDelegate {
|
|||
|
||||
}
|
||||
|
||||
// MARK: private functions related to M5Stack
|
||||
// MARK: - private functions related to M5Stack
|
||||
|
||||
/// send all parameters to m5Stack
|
||||
/// - parameters:
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
"watlaaViewscreenTitle" = "Watlaa";
|
|
@ -19,7 +19,7 @@
|
|||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>3191</string>
|
||||
<string>3234</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import Foundation
|
||||
|
||||
class TextsWatlaaView {
|
||||
|
||||
static private let filename = "WatlaaView"
|
||||
|
||||
static let watlaaViewscreenTitle: String = {
|
||||
return NSLocalizedString("watlaaViewscreenTitle", tableName: filename, bundle: Bundle.main, value: "Watlaa", comment: "when Watlaa list is shown, title of the view")
|
||||
}()
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -227,17 +227,17 @@ class BluetoothPeripheralViewController: UIViewController {
|
|||
/// user cliks done button
|
||||
public func doneButtonHandler() {
|
||||
|
||||
if let bluetoothPeripheralASNSObject = bluetoothPeripheralAsNSObject, let coreDataManager = coreDataManager {
|
||||
if let bluetoothPeripheralAsNSObject = bluetoothPeripheralAsNSObject, let coreDataManager = coreDataManager {
|
||||
|
||||
// set variable delegate in bluetoothPeripheralASNSObject to nil, no need anymore to receive info
|
||||
bluetoothPeripheralManager.getBluetoothTransmitter(for: bluetoothPeripheralASNSObject, createANewOneIfNecesssary: false)?.variableBluetoothTransmitterDelegate = nil
|
||||
bluetoothPeripheralManager.getBluetoothTransmitter(for: bluetoothPeripheralAsNSObject, createANewOneIfNecesssary: false)?.variableBluetoothTransmitterDelegate = nil
|
||||
|
||||
// set alias temp value, possibly this is a nil value
|
||||
bluetoothPeripheralASNSObject.setAlias(aliasTemporaryValue)
|
||||
bluetoothPeripheralAsNSObject.setAlias(aliasTemporaryValue)
|
||||
|
||||
|
||||
// temp values stored by viewmodel needs to be written to bluetoothPeripheralASNSObject
|
||||
bluetoothPeripheralViewModel.writeTempValues(to: bluetoothPeripheralASNSObject)
|
||||
bluetoothPeripheralViewModel.writeTempValues(to: bluetoothPeripheralAsNSObject)
|
||||
|
||||
// save all changes now
|
||||
coreDataManager.saveChanges()
|
||||
|
|
|
@ -516,7 +516,7 @@ class M5StackBluetoothPeripheralViewModel {
|
|||
|
||||
}
|
||||
|
||||
// MARK: - extension BluetoothTransmitterDelegate
|
||||
// MARK: - conform to BluetoothTransmitterDelegate
|
||||
|
||||
extension M5StackBluetoothPeripheralViewModel: BluetoothTransmitterDelegate {
|
||||
|
||||
|
@ -535,7 +535,7 @@ extension M5StackBluetoothPeripheralViewModel: BluetoothTransmitterDelegate {
|
|||
|
||||
}
|
||||
|
||||
// MARK: - extension M5StackBluetoothTransmitterDelegate
|
||||
// MARK: - conform to M5StackBluetoothTransmitterDelegate
|
||||
|
||||
extension M5StackBluetoothPeripheralViewModel: M5StackBluetoothTransmitterDelegate {
|
||||
|
||||
|
@ -773,12 +773,12 @@ extension M5StackBluetoothPeripheralViewModel: BluetoothPeripheralViewModel {
|
|||
|
||||
self.bluetoothTransmitterDelegate = bluetoothTransmitterDelegate
|
||||
|
||||
if let m5StackPeripheral = bluetoothPeripheral as? M5Stack {
|
||||
if let m5Stack = bluetoothPeripheral as? M5Stack {
|
||||
|
||||
storeTempValues(from: m5StackPeripheral)
|
||||
storeTempValues(from: m5Stack)
|
||||
|
||||
// also request batteryLevel, this may have been updated
|
||||
if let blueToothTransmitter = bluetoothPeripheralManager.getBluetoothTransmitter(for: m5StackPeripheral, createANewOneIfNecesssary: false), let m5StackBluetoothTransmitter = blueToothTransmitter as? M5StackBluetoothTransmitter {
|
||||
if let blueToothTransmitter = bluetoothPeripheralManager.getBluetoothTransmitter(for: m5Stack, createANewOneIfNecesssary: false), let m5StackBluetoothTransmitter = blueToothTransmitter as? M5StackBluetoothTransmitter {
|
||||
|
||||
_ = m5StackBluetoothTransmitter.readBatteryLevel()
|
||||
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
import UIKit
|
||||
import CoreBluetooth
|
||||
|
||||
class WatlaaMasterBluetoothPeripheralViewModel {
|
||||
|
||||
// MARK: - private properties
|
||||
|
||||
/// settings correspond to watlaa specific rows in viewcontroller
|
||||
private enum WatlaaSetting: Int, CaseIterable {
|
||||
|
||||
/// batteryLevel
|
||||
case batteryLevel
|
||||
|
||||
}
|
||||
|
||||
/// reference to bluetoothPeripheralManager
|
||||
private weak var bluetoothPeripheralManager: BluetoothPeripheralManaging?
|
||||
|
||||
/// reference to the tableView
|
||||
private weak var tableView: UITableView?
|
||||
|
||||
/// reference to BluetoothPeripheralViewController that will own this WatlaaMasterBluetoothPeripheralViewModel - needed to present stuff etc
|
||||
private weak var bluetoothPeripheralViewController: BluetoothPeripheralViewController?
|
||||
|
||||
private weak var bluetoothTransmitterDelegate: BluetoothTransmitterDelegate?
|
||||
|
||||
|
||||
}
|
||||
|
||||
// MARK: - conform to BluetoothPeripheralViewModel
|
||||
|
||||
extension WatlaaMasterBluetoothPeripheralViewModel: BluetoothPeripheralViewModel {
|
||||
|
||||
func configure(bluetoothPeripheral: BluetoothPeripheral?, bluetoothPeripheralManager: BluetoothPeripheralManaging, tableView: UITableView, bluetoothPeripheralViewController: BluetoothPeripheralViewController, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate) {
|
||||
|
||||
self.bluetoothPeripheralManager = bluetoothPeripheralManager
|
||||
|
||||
self.tableView = tableView
|
||||
|
||||
self.bluetoothPeripheralViewController = bluetoothPeripheralViewController
|
||||
|
||||
self.bluetoothTransmitterDelegate = bluetoothTransmitterDelegate
|
||||
|
||||
if let watlaaPeripheral = bluetoothPeripheral as? Watlaa {
|
||||
|
||||
storeTempValues(from: watlaaPeripheral)
|
||||
|
||||
// also request batteryLevel, this may have been updated
|
||||
if let blueToothTransmitter = bluetoothPeripheralManager.getBluetoothTransmitter(for: watlaaPeripheral, createANewOneIfNecesssary: false), let watlaaBluetoothTransmitter = blueToothTransmitter as? WatlaaBluetoothTransmitterMaster {
|
||||
|
||||
_ = watlaaBluetoothTransmitter.readBatteryLevel()
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func screenTitle() -> String {
|
||||
return TextsWatlaaView.watlaaViewscreenTitle
|
||||
}
|
||||
|
||||
func sectionTitle(forSection section: Int) -> String {
|
||||
return "section title tbc"
|
||||
}
|
||||
|
||||
func update(cell: UITableViewCell, forRow rawValue: Int, forSection section: Int, for bluetoothPeripheral: BluetoothPeripheral, doneButtonOutlet: UIBarButtonItem) {
|
||||
|
||||
// verify that bluetoothPeripheralAsNSObject is an M5Stack
|
||||
guard let watlaa = bluetoothPeripheral as? Watlaa else {
|
||||
fatalError("WatlaaMasterBluetoothPeripheralViewModel update, bluetoothPeripheral is not Watlaa")
|
||||
}
|
||||
|
||||
// default value for accessoryView is nil
|
||||
cell.accessoryView = nil
|
||||
|
||||
switch section {
|
||||
|
||||
case 1:
|
||||
|
||||
guard let setting = WatlaaSetting(rawValue: rawValue) else { fatalError("WatlaaMasterBluetoothPeripheralViewModel update, unexpected setting") }
|
||||
|
||||
switch setting {
|
||||
|
||||
case .batteryLevel:
|
||||
|
||||
cell.textLabel?.text = Texts_BluetoothPeripheralsView.batteryLevel
|
||||
cell.detailTextLabel?.text = watlaa.batteryLevel?.description
|
||||
cell.accessoryType = .none
|
||||
|
||||
}
|
||||
|
||||
default:
|
||||
fatalError("in WatlaaMasterBluetoothPeripheralViewModel update, unhandled section number")
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func userDidSelectRow(withSettingRawValue rawValue: Int, forSection section: Int, for bluetoothPeripheral: BluetoothPeripheral, bluetoothPeripheralManager: BluetoothPeripheralManaging, doneButtonOutlet: UIBarButtonItem) {
|
||||
|
||||
switch section {
|
||||
|
||||
case 1:
|
||||
|
||||
guard let setting = WatlaaSetting(rawValue: rawValue) else { fatalError("WatlaaMasterBluetoothPeripheralViewModel userDidSelectRow, unexpected setting") }
|
||||
|
||||
switch setting {
|
||||
|
||||
case .batteryLevel:
|
||||
// user can't do anything by clicking on battery row
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
default:
|
||||
fatalError("in WatlaaMasterBluetoothPeripheralViewModel update, unhandled section number")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func numberOfSettings(inSection section: Int) -> Int {
|
||||
return WatlaaSetting.allCases.count
|
||||
}
|
||||
|
||||
func numberOfSections() -> Int {
|
||||
// for the moment only one specific section for watlaa
|
||||
return 1
|
||||
}
|
||||
|
||||
func storeTempValues(from bluetoothPeripheral: BluetoothPeripheral) {
|
||||
}
|
||||
|
||||
func writeTempValues(to bluetoothPeripheral: BluetoothPeripheral) {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// MARK: - conform to BluetoothTransmitterDelegate
|
||||
|
||||
extension WatlaaMasterBluetoothPeripheralViewModel: BluetoothTransmitterDelegate {
|
||||
|
||||
func didConnectTo(bluetoothTransmitter: BluetoothTransmitter) {
|
||||
bluetoothTransmitterDelegate?.didConnectTo(bluetoothTransmitter: bluetoothTransmitter)
|
||||
}
|
||||
|
||||
func didDisconnectFrom(bluetoothTransmitter: BluetoothTransmitter) {
|
||||
bluetoothTransmitterDelegate?.didDisconnectFrom(bluetoothTransmitter: bluetoothTransmitter)
|
||||
}
|
||||
|
||||
func deviceDidUpdateBluetoothState(state: CBManagerState, bluetoothTransmitter: BluetoothTransmitter) {
|
||||
bluetoothTransmitterDelegate?.deviceDidUpdateBluetoothState(state: state, bluetoothTransmitter: bluetoothTransmitter)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// MARK: - conform to WatlaaBluetoothTransmitterDelegate
|
||||
|
||||
extension WatlaaMasterBluetoothPeripheralViewModel: WatlaaBluetoothTransmitterDelegate {
|
||||
|
||||
func isReadyToReceiveData(watlaaBluetoothTransmitter: WatlaaBluetoothTransmitterMaster) {
|
||||
// viewcontroller doesn't use this
|
||||
}
|
||||
|
||||
func receivedBattery(level: Int, watlaaBluetoothTransmitter: WatlaaBluetoothTransmitterMaster) {
|
||||
|
||||
// batteryLevel should get updated in Watlaa object by bluetoothPeripheralManager, here's the trigger to update the table
|
||||
tableView?.reloadRows(at: [IndexPath(row: WatlaaSetting.batteryLevel.rawValue, section: 1)], with: .none)
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -408,7 +408,12 @@ final class RootViewController: UIViewController {
|
|||
})
|
||||
|
||||
// setup bluetoothPeripheralManager
|
||||
bluetoothPeripheralManager = BluetoothPeripheralManager(coreDataManager: coreDataManager)
|
||||
bluetoothPeripheralManager = BluetoothPeripheralManager(coreDataManager: coreDataManager, cgmTransmitterDelegate: self, onCGMTransmitterCreation: {
|
||||
(cgmTransmitter: CGMTransmitter?) in
|
||||
|
||||
self.cgmTransmitter = cgmTransmitter
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
@ -813,6 +818,10 @@ final class RootViewController: UIViewController {
|
|||
case .blueReader:
|
||||
cgmTransmitter = CGMBlueReaderTransmitter(address: UserDefaults.standard.cgmTransmitterDeviceAddress, name: UserDefaults.standard.cgmTransmitterDeviceName, delegate: self)
|
||||
|
||||
case .watlaa:
|
||||
// watlaa transmitter needs to be set through bluetooth devices tab
|
||||
cgmTransmitter = nil
|
||||
|
||||
}
|
||||
|
||||
// assign calibrator
|
||||
|
@ -820,7 +829,7 @@ final class RootViewController: UIViewController {
|
|||
|
||||
case .dexcomG4, .dexcomG5, .dexcomG6:
|
||||
calibrator = DexcomCalibrator()
|
||||
case .miaomiao, .GNSentry, .Blucon, .Bubble, .Droplet1, .blueReader:
|
||||
case .miaomiao, .GNSentry, .Blucon, .Bubble, .Droplet1, .blueReader, .watlaa:
|
||||
// for all transmitters used with Libre1, calibrator is either NoCalibrator or Libre1Calibrator, depending if oopWeb is supported by the transmitter and on value of webOOPEnabled in settings
|
||||
calibrator = RootViewController.getCalibrator(transmitterType: selectedTransmitterType, webOOPEnabled: UserDefaults.standard.webOOPEnabled)
|
||||
}
|
||||
|
@ -1329,6 +1338,10 @@ final class RootViewController: UIViewController {
|
|||
/// conform to CGMTransmitterDelegate
|
||||
extension RootViewController:CGMTransmitterDelegate {
|
||||
|
||||
func getCGMTransmitter() -> CGMTransmitter? {
|
||||
return cgmTransmitter
|
||||
}
|
||||
|
||||
func error(message: String) {
|
||||
|
||||
let alert = UIAlertController(title: Texts_Common.warning, message: message, actionHandler: nil)
|
||||
|
|
Loading…
Reference in New Issue