Libre 2 : should support oop web without having to use first Bubble or MM - also serial number and battery are shown now in bluetooth screen

This commit is contained in:
Johan Degraeve 2021-01-05 22:44:45 +01:00
parent a7f2981e81
commit 67ec6b0ef4
8 changed files with 143 additions and 24 deletions

View File

@ -289,6 +289,36 @@ class CGMLibre2Transmitter:BluetoothTransmitter, CGMTransmitter {
extension CGMLibre2Transmitter: LibreNFCDelegate {
func received(fram: Data) {
trace("received fram : %{public}@", log: log, category: ConstantsLog.categoryCGMLibre2, type: .info, fram.toHexString())
// first get sensor status and send to delegate
if fram.count >= 5 {
let sensorState = LibreSensorState(stateByte: fram[4])
cGMLibre2TransmitterDelegate?.received(sensorStatus: sensorState, from: self)
}
// if we already know the patchinfo (which we should because normally received(patchInfo: Data gets called before received(fram: Data), then patchInfo should not be nil
// same for sensorUID
if let patchInfo = UserDefaults.standard.librePatchInfo, let sensorUID = UserDefaults.standard.libreSensorUID, let libreSensorType = LibreSensorType.type(patchInfo: patchInfo.hexEncodedString().uppercased()), let serialNumber = self.sensorSerialNumber {
var framCopy = fram
if libreSensorType.decryptIfPossibleAndNeeded(rxBuffer: &framCopy, headerLength: 0, log: log, patchInfo: patchInfo.hexEncodedString().uppercased(), uid: sensorUID.bytes) {
// we have all date to create libre1DerivedAlgorithmParameters
UserDefaults.standard.libre1DerivedAlgorithmParameters = Libre1DerivedAlgorithmParameters(bytes: framCopy, serialNumber: serialNumber)
}
}
}
func received(sensorUID: Data) {
// store sensorUID as data in UserDefaults
@ -308,6 +338,8 @@ extension CGMLibre2Transmitter: LibreNFCDelegate {
cgmTransmitterDelegate?.newSensorDetected()
cGMLibre2TransmitterDelegate?.received(serialNumber: receivedSensorSerialNumber, from: self)
}
} else {

View File

@ -2,4 +2,10 @@ import Foundation
protocol CGMLibre2TransmitterDelegate: AnyObject {
/// received sensor Serial Number
func received(serialNumber: String, from cGMLibre2Transmitter: CGMLibre2Transmitter)
/// Libre 2 is sending sensorStatus
func received(sensorStatus: LibreSensorState, from cGMLibre2Transmitter: CGMLibre2Transmitter)
}

View File

@ -196,7 +196,9 @@ class LibreNFC: NSObject, NFCTagReaderSessionDelegate {
let patchInfo = response
self.libreNFCDelegate?.received(patchInfo: patchInfo)
self.tracePatchInfo(patchInfo: patchInfo)
// send FRAM to delegate
self.libreNFCDelegate?.received(fram: fram)
msg = "NFC: dump of "

View File

@ -1,11 +1,13 @@
import Foundation
/// some functions to send sensorUID and patchInfo, unlockcode etc. to delegate
/// some functions to send FRAM, sensorUID and patchInfo, unlockcode etc. to delegate
protocol LibreNFCDelegate: AnyObject {
func received(sensorUID: Data)
func received(patchInfo: Data)
func received(fram: Data)
func streamingEnabled(successful : Bool)

View File

@ -210,7 +210,7 @@ extension UserDefaults {
case addDebugLevelLogsInTraceFileAndNSLog = "addDebugLevelLogsInTraceFileAndNSLog"
// non fixed slope values for oop web Libre
/// web oop parameters, only for Libre 1
/// web oop parameters, only for bubble, miaomiao and Libre 2
case libre1DerivedAlgorithmParameters = "algorithmParameters"
// development settings
@ -1278,7 +1278,7 @@ extension UserDefaults {
}
}
/// web oop parameters, only for bubble
/// web oop parameters, only for bubble, miaomiao and Libre 2
var libre1DerivedAlgorithmParameters: Libre1DerivedAlgorithmParameters? {
get {
guard let jsonString = string(forKey: Key.libre1DerivedAlgorithmParameters.rawValue) else { return nil }

View File

@ -2,4 +2,34 @@ import Foundation
extension BluetoothPeripheralManager: CGMLibre2TransmitterDelegate {
func received(serialNumber: String, from cGMLibre2Transmitter: CGMLibre2Transmitter) {
guard let libre2 = findTransmitter(cGMLibre2Transmitter: cGMLibre2Transmitter) else {return}
// store serial number in Libre2 object
libre2.blePeripheral.sensorSerialNumber = serialNumber
coreDataManager.saveChanges()
}
func received(sensorStatus: LibreSensorState, from cGMLibre2Transmitter: CGMLibre2Transmitter) {
guard let libre2 = findTransmitter(cGMLibre2Transmitter: cGMLibre2Transmitter) else {return}
// store sensor state Libre 2 object
libre2.sensorState = sensorStatus
// no coredatamanager savechanges needed because sensor state is not stored in coredata
}
private func findTransmitter(cGMLibre2Transmitter: CGMLibre2Transmitter) -> Libre2? {
guard let index = bluetoothTransmitters.firstIndex(of: cGMLibre2Transmitter), let libre2 = bluetoothPeripherals[index] as? Libre2 else {return nil}
return libre2
}
}

View File

@ -5,8 +5,11 @@ class Libre2BluetoothPeripheralViewModel {
/// settings specific for Libre2
private enum Settings: Int, CaseIterable {
/// battery level
case batteryLevel = 0
/// Sensor serial number
case sensorSerialNumber = 0
/// sensor State
case sensorState = 1
}
@ -32,6 +35,9 @@ class Libre2BluetoothPeripheralViewModel {
}
}
/// Libre 2 settings will be in section 0 + numberOfGeneralSections
private let sectionNumberForMiaoMiaoSpecificSettings = 0
// MARK: - deinit
deinit {
@ -97,9 +103,9 @@ extension Libre2BluetoothPeripheralViewModel: BluetoothPeripheralViewModel {
func update(cell: UITableViewCell, forRow rawValue: Int, forSection section: Int, for bluetoothPeripheral: BluetoothPeripheral) {
// verify that bluetoothPeripheral is a Libre2
/*guard let Libre2 = bluetoothPeripheral as? Libre2 else {
guard let libre2 = bluetoothPeripheral as? Libre2 else {
fatalError("Libre2BluetoothPeripheralViewModel update, bluetoothPeripheral is not Libre2")
}*/
}
// default value for accessoryView is nil
cell.accessoryView = nil
@ -108,14 +114,18 @@ extension Libre2BluetoothPeripheralViewModel: BluetoothPeripheralViewModel {
switch setting {
case .batteryLevel:
case .sensorState:
cell.textLabel?.text = Texts_BluetoothPeripheralsView.batteryLevel
// not yet supported, can we get the battery level for Libre 2 ?
cell.detailTextLabel?.text = ""
cell.accessoryType = .none
cell.textLabel?.text = Texts_Common.sensorStatus
cell.detailTextLabel?.text = libre2.sensorState.translatedDescription
case .sensorSerialNumber:
cell.textLabel?.text = Texts_BluetoothPeripheralView.sensorSerialNumber
cell.detailTextLabel?.text = libre2.blePeripheral.sensorSerialNumber
cell.accessoryType = .disclosureIndicator
}
@ -123,15 +133,29 @@ extension Libre2BluetoothPeripheralViewModel: BluetoothPeripheralViewModel {
func userDidSelectRow(withSettingRawValue rawValue: Int, forSection section: Int, for bluetoothPeripheral: BluetoothPeripheral, bluetoothPeripheralManager: BluetoothPeripheralManaging) -> SettingsSelectedRowAction {
// verify that bluetoothPeripheral is a Libre2
guard let libre2 = bluetoothPeripheral as? Libre2 else {
fatalError("Libre2BluetoothPeripheralViewModel update, bluetoothPeripheral is not Libre2")
}
guard let setting = Settings(rawValue: rawValue) else { fatalError("Libre2BluetoothPeripheralViewModel userDidSelectRow, unexpected setting") }
switch setting {
case .batteryLevel:
case .sensorState:
return .nothing
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 = libre2.blePeripheral.sensorSerialNumber {
return .showInfoText(title: Texts_HomeView.info, message: Texts_BluetoothPeripheralView.sensorSerialNumber + " : " + serialNumber)
}
}
return .nothing
}
func numberOfSettings(inSection section: Int) -> Int {
@ -139,7 +163,7 @@ extension Libre2BluetoothPeripheralViewModel: BluetoothPeripheralViewModel {
}
func numberOfSections() -> Int {
// for the moment only one specific section for DexcomG5
// for the moment only one specific section for Libre2
return 1
}
@ -150,5 +174,35 @@ extension Libre2BluetoothPeripheralViewModel: BluetoothPeripheralViewModel {
extension Libre2BluetoothPeripheralViewModel: CGMLibre2TransmitterDelegate {
func received(sensorStatus: LibreSensorState, from cGMLibre2Transmitter: CGMLibre2Transmitter) {
// inform also bluetoothPeripheralManager
(bluetoothPeripheralManager as? CGMLibre2TransmitterDelegate)?.received(sensorStatus: sensorStatus, from: cGMLibre2Transmitter)
// here's the trigger to update the table
reloadRow(row: Settings.sensorState.rawValue)
}
func received(serialNumber: String, from cGMLibre2Transmitter: CGMLibre2Transmitter) {
// inform also bluetoothPeripheralManager
(bluetoothPeripheralManager as? CGMLibre2TransmitterDelegate)?.received(serialNumber: serialNumber, from: cGMLibre2Transmitter)
// here's the trigger to update the table
reloadRow(row: Settings.sensorSerialNumber.rawValue)
}
private func reloadRow(row: Int) {
if let bluetoothPeripheralViewController = bluetoothPeripheralViewController {
tableView?.reloadRows(at: [IndexPath(row: row, section: bluetoothPeripheralViewController.numberOfGeneralSections() + sectionNumberForMiaoMiaoSpecificSettings)], with: .none)
}
}
}

View File

@ -1852,10 +1852,3 @@ extension RootViewController: UIGestureRecognizerDelegate {
}
}
// MARK: - conform to CGMLibre2TransmitterDelegate
extension RootViewController: CGMLibre2TransmitterDelegate {
}