Dexcom G4 with xdrip

This commit is contained in:
Johan Degraeve 2020-04-05 21:48:39 +02:00
parent 6a06c650f0
commit 0cc70f2a2d
14 changed files with 373 additions and 22 deletions

View File

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

View File

@ -19,6 +19,9 @@ enum BluetoothPeripheralType: String, CaseIterable {
/// DexcomG5
case DexcomG5Type = "Dexcom G5"
/// DexcomG4
case DexcomG4Type = "Dexcom G4 (bridge)"
/// bubble
case BubbleType = "Bubble"
@ -72,6 +75,9 @@ enum BluetoothPeripheralType: String, CaseIterable {
case .DropletType:
return DropletBluetoothPeripheralViewModel()
case .DexcomG4Type:
return DexcomG4BluetoothPeripheralViewModel()
}
}
@ -125,6 +131,10 @@ enum BluetoothPeripheralType: String, CaseIterable {
return Droplet(address: address, name: name, alias: nil, nsManagedObjectContext: nsManagedObjectContext)
case .DexcomG4Type:
return DexcomG4(address: address, name: name, alias: nil, nsManagedObjectContext: nsManagedObjectContext)
}
}
@ -143,7 +153,7 @@ enum BluetoothPeripheralType: String, CaseIterable {
case .watlaaMaster:
return .watlaa
case .DexcomG5Type, .BubbleType, .MiaoMiaoType, .BluconType, .GNSentryType, .BlueReaderType, .DropletType:
case .DexcomG5Type, .BubbleType, .MiaoMiaoType, .BluconType, .GNSentryType, .BlueReaderType, .DropletType, .DexcomG4Type:
return .CGM
}
@ -158,7 +168,7 @@ enum BluetoothPeripheralType: String, CaseIterable {
case .M5StackType, .M5StickCType, .watlaaMaster, .BubbleType, .MiaoMiaoType, .GNSentryType, .BlueReaderType, .DropletType:
return false
case .DexcomG5Type, .BluconType:
case .DexcomG5Type, .BluconType, .DexcomG4Type:
return true
}
@ -194,8 +204,8 @@ enum BluetoothPeripheralType: String, CaseIterable {
// validation successful
return nil
/*case .dexcomG4:
//verify allowed chars
case .DexcomG4Type:
let regex = try! NSRegularExpression(pattern: "[a-zA-Z0-9]", options: .caseInsensitive)
if !transmitterId.validate(withRegex: regex) {
return Texts_ErrorMessages.DexcomTransmitterIDInvalidCharacters
@ -205,15 +215,6 @@ enum BluetoothPeripheralType: String, CaseIterable {
}
return nil
case .miaomiao, .GNSentry, .Bubble, .Droplet1:
return nil
case .blueReader:
return nil
case .watlaa:
return nil*/
case .M5StackType, .M5StickCType, .watlaaMaster, .BubbleType, .MiaoMiaoType, .GNSentryType, .BlueReaderType, .DropletType:
// no transmitter id means no validation to do
return nil
@ -268,6 +269,10 @@ enum BluetoothPeripheralType: String, CaseIterable {
case .DropletType:
return false
case .DexcomG4Type:
return false
}
}

View File

@ -0,0 +1,8 @@
import Foundation
protocol CGMDexcomG4TransmitterDelegate: AnyObject {
/// DexcomG4 is sending batteryLevel
func received(batteryLevel: Int, from cGMG4xDripTransmitter: CGMG4xDripTransmitter)
}

View File

@ -18,6 +18,9 @@ final class CGMG4xDripTransmitter: BluetoothTransmitter, CGMTransmitter {
/// will be used to pass back bluetooth and cgm related events
private(set) weak var cgmTransmitterDelegate:CGMTransmitterDelegate?
/// CGMDexcomG4TransmitterDelegate
public weak var cGMDexcomG4TransmitterDelegate: CGMDexcomG4TransmitterDelegate?
/// for trace
private let log = OSLog(subsystem: ConstantsLog.subSystem, category: ConstantsLog.categoryCGMxDripG4)
@ -32,7 +35,7 @@ final class CGMG4xDripTransmitter: BluetoothTransmitter, CGMTransmitter {
/// - transmitterID: expected transmitterID, 5 characters
/// - bluetoothTransmitterDelegate : a BluetoothTransmitterDelegate
/// - cGMTransmitterDelegate : a CGMTransmitterDelegate
init(address:String?, name: String?, transmitterID:String, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate, cGMTransmitterDelegate:CGMTransmitterDelegate) {
init(address:String?, name: String?, transmitterID:String, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate, cGMDexcomG4TransmitterDelegate : CGMDexcomG4TransmitterDelegate, cGMTransmitterDelegate:CGMTransmitterDelegate) {
// assign addressname and name or expected devicename
var newAddressAndName:BluetoothTransmitter.DeviceAddressAndName = BluetoothTransmitter.DeviceAddressAndName.notYetConnected(expectedName: nil)
if let address = address {
@ -42,6 +45,9 @@ final class CGMG4xDripTransmitter: BluetoothTransmitter, CGMTransmitter {
//assign CGMTransmitterDelegate
self.cgmTransmitterDelegate = cGMTransmitterDelegate
// assign cGMDexcomG4TransmitterDelegate
self.cGMDexcomG4TransmitterDelegate = cGMDexcomG4TransmitterDelegate
//assign transmitterId
self.transmitterId = transmitterID
@ -83,7 +89,7 @@ final class CGMG4xDripTransmitter: BluetoothTransmitter, CGMTransmitter {
//process value and get result
let result = processxBridgeDataPacket(value: value)
// check transmitterid, if not correct write correct value and return
// check transmitterid, if not correct write correct value to the bridge, and return
if let data = checkTransmitterId(receivedTransmitterId: result.transmitterID, expectedTransmitterId: self.transmitterId, log: log) {
trace(" in peripheralDidUpdateValueFor, sending transmitterid %{public}@ to xdrip ", log: log, category: ConstantsLog.categoryCGMxDripG4, type: .info, self.transmitterId)
_ = writeDataToPeripheral(data: data, type: .withoutResponse)//no need to log the result, this is already logged in BluetoothTransmitter.swift
@ -93,14 +99,25 @@ final class CGMG4xDripTransmitter: BluetoothTransmitter, CGMTransmitter {
// Data packet Acknowledgement, to put wixel to sleep
_ = writeDataToPeripheral(data: Data([0x02,0xF0]), type: .withoutResponse)
// if glucoseData received, send to delegate. If transmitterBatteryInfo available, then also send this to cGMDexcomG4TransmitterDelegate
if let glucoseData = result.glucoseData {
var glucoseDataArray = [glucoseData]
var transmitterBatteryInfo:TransmitterBatteryInfo? = nil
if let level = result.batteryLevel {
transmitterBatteryInfo = TransmitterBatteryInfo.DexcomG4(level: level)
cGMDexcomG4TransmitterDelegate?.received(batteryLevel: level, from: self)
}
cgmTransmitterDelegate?.cgmTransmitterInfoReceived(glucoseData: &glucoseDataArray, transmitterBatteryInfo: transmitterBatteryInfo, sensorTimeInMinutes: nil)
}
case .beaconPacket?:
trace(" in peripheral didUpdateValueFor, received beaconPacket", log: log, category: ConstantsLog.categoryCGMxDripG4, type: .info)
@ -129,8 +146,12 @@ final class CGMG4xDripTransmitter: BluetoothTransmitter, CGMTransmitter {
if let glucoseData = result.glucoseData {
var glucoseDataArray = [glucoseData]
var transmitterBatteryInfo:TransmitterBatteryInfo? = nil
if let batteryLevel = result.batteryLevel {
transmitterBatteryInfo = TransmitterBatteryInfo.DexcomG4(level: batteryLevel)
if let level = result.batteryLevel {
transmitterBatteryInfo = TransmitterBatteryInfo.DexcomG4(level: level)
cGMDexcomG4TransmitterDelegate?.received(batteryLevel: level, from: self)
}
cgmTransmitterDelegate?.cgmTransmitterInfoReceived(glucoseData: &glucoseDataArray, transmitterBatteryInfo: transmitterBatteryInfo, sensorTimeInMinutes: nil)
}

View File

@ -1,6 +1,9 @@
/// constants related to Libre OOP
enum ConstantsLibreOOP {
/// is web oop enabled by default yes or no
static let defaultWebOOPEnabled = false
/// site for libreOOP client
static let site = "http://www.glucose.space/calibrateSensor"

View File

@ -18,7 +18,7 @@ public class BLEPeripheral: NSManagedObject {
self.alias = alias
self.parameterUpdateNeededAtNextConnect = false
webOOPEnabled = false
webOOPEnabled = ConstantsLibreOOP.defaultWebOOPEnabled
}

View File

@ -61,6 +61,9 @@ extension BLEPeripheral {
// a BLEPeripheral should only have one of dexcomG5, watlaa, m5Stack, ...
@NSManaged public var blucon: Blucon?
// a BLEPeripheral should only have one of dexcomG5, watlaa, m5Stack, ...
@NSManaged public var dexcomG4: DexcomG4?
/// sensorSerialNumber of last sensor that was read
@NSManaged public var sensorSerialNumber: String?

View File

@ -0,0 +1,24 @@
import Foundation
import CoreData
public class DexcomG4: NSManagedObject {
/// batterylevel, not stored in coreData, will only be available after having received it from the M5Stack
public var batteryLevel: Int = 0
/// create DexcomG4
/// - parameters:
init(address: String, name: String, alias: String?, nsManagedObjectContext:NSManagedObjectContext) {
let entity = NSEntityDescription.entity(forEntityName: "DexcomG4", in: nsManagedObjectContext)!
super.init(entity: entity, insertInto: nsManagedObjectContext)
blePeripheral = BLEPeripheral(address: address, name: name, alias: nil, nsManagedObjectContext: nsManagedObjectContext)
}
private override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?) {
super.init(entity: entity, insertInto: context)
}
}

View File

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

View File

@ -52,6 +52,7 @@
<relationship name="blucon" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Blucon" inverseName="blePeripheral" inverseEntity="Blucon"/>
<relationship name="blueReader" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="BlueReader" inverseName="blePeripheral" inverseEntity="BlueReader"/>
<relationship name="bubble" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Bubble" inverseName="blePeripheral" inverseEntity="Bubble"/>
<relationship name="dexcomG4" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="DexcomG4" inverseName="blePeripheral" inverseEntity="DexcomG4"/>
<relationship name="dexcomG5" optional="YES" maxCount="1" deletionRule="Deny" destinationEntity="DexcomG5" inverseName="blePeripheral" inverseEntity="DexcomG5"/>
<relationship name="droplet" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Droplet" inverseName="blePeripheral" inverseEntity="Droplet"/>
<relationship name="gNSEntry" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="GNSEntry" inverseName="blePeripheral" inverseEntity="GNSEntry"/>
@ -90,6 +91,9 @@
<relationship name="bgreadings" toMany="YES" deletionRule="Deny" destinationEntity="BgReading" inverseName="calibration" inverseEntity="BgReading"/>
<relationship name="sensor" maxCount="1" deletionRule="Nullify" destinationEntity="Sensor" inverseName="calibrations" inverseEntity="Sensor"/>
</entity>
<entity name="DexcomG4" representedClassName=".DexcomG4" syncable="YES">
<relationship name="blePeripheral" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="BLEPeripheral" inverseName="dexcomG4" inverseEntity="BLEPeripheral"/>
</entity>
<entity name="DexcomG5" representedClassName=".DexcomG5" syncable="YES">
<attribute name="batteryResist" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="batteryRuntime" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
@ -142,7 +146,7 @@
<element name="AlertEntry" positionX="-648" positionY="189" width="128" height="105"/>
<element name="AlertType" positionX="-657" positionY="180" width="128" height="165"/>
<element name="BgReading" positionX="-285.87109375" positionY="31.9921875" width="128" height="330"/>
<element name="BLEPeripheral" positionX="-630" positionY="216" width="128" height="343"/>
<element name="BLEPeripheral" positionX="-630" positionY="216" width="128" height="358"/>
<element name="Blucon" positionX="-657" positionY="189" width="128" height="73"/>
<element name="BlueReader" positionX="-639" positionY="207" width="128" height="58"/>
<element name="Bubble" positionX="-657" positionY="189" width="128" height="103"/>
@ -154,5 +158,6 @@
<element name="Sensor" positionX="-603.0859375" positionY="482.2890625" width="128" height="133"/>
<element name="Watlaa" positionX="-639" positionY="207" width="128" height="58"/>
<element name="Droplet" positionX="-630" positionY="216" width="128" height="58"/>
<element name="DexcomG4" positionX="-621" positionY="225" width="128" height="58"/>
</elements>
</model>

View File

@ -0,0 +1,25 @@
import Foundation
extension BluetoothPeripheralManager: CGMDexcomG4TransmitterDelegate {
func received(batteryLevel: Int, from cGMG4xDripTransmitter: CGMG4xDripTransmitter) {
guard let DexcomG4 = findTransmitter(cGMG4xDripTransmitter: cGMG4xDripTransmitter) else {return}
// store serial number in DexcomG4 object
DexcomG4.batteryLevel = batteryLevel
// no coredatamanager savechanges needed because batterylevel is not stored in coredata
}
private func findTransmitter(cGMG4xDripTransmitter: CGMG4xDripTransmitter) -> DexcomG4? {
guard let index = bluetoothTransmitters.firstIndex(of: cGMG4xDripTransmitter), let DexcomG4 = bluetoothPeripherals[index] as? DexcomG4 else {return nil}
return DexcomG4
}
}

View File

@ -230,6 +230,37 @@ class BluetoothPeripheralManager: NSObject {
}
case .DexcomG4Type:
if let dexcomG4 = blePeripheral.dexcomG4 {
// add it to the list of bluetoothPeripherals
let index = insertInBluetoothPeripherals(bluetoothPeripheral: dexcomG4)
if dexcomG4.blePeripheral.shouldconnect {
if let transmitterId = dexcomG4.blePeripheral.transmitterId {
// create an instance of CGMDexcomG4Transmitter, CGMDexcomG4Transmitter will automatically try to connect to the Bubble with the address that is stored in bubble
// add it to the array of bluetoothTransmitters
bluetoothTransmitters.insert(CGMG4xDripTransmitter(address: dexcomG4.blePeripheral.address, name: dexcomG4.blePeripheral.name, transmitterID: transmitterId, bluetoothTransmitterDelegate: self, cGMDexcomG4TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate), at: index)
// if DexcomG4Type is of type CGM, then assign the address to currentCgmTransmitterAddress, there shouldn't be any other bluetoothPeripherals of type .CGM with shouldconnect = true
if bluetoothPeripheralType.category() == .CGM {
currentCgmTransmitterAddress = blePeripheral.address
}
}
} else {
// bluetoothTransmitters array (which shoul dhave the same number of elements as bluetoothPeripherals) needs to have an empty row for the transmitter
bluetoothTransmitters.insert(nil, at: index)
}
}
case .DropletType:
if let droplet = blePeripheral.droplet {
@ -397,7 +428,7 @@ class BluetoothPeripheralManager: NSObject {
// no need to send reading to watlaa in master mode
break
case .DexcomG5Type, .BubbleType, .MiaoMiaoType, .BluconType, .GNSentryType, .BlueReaderType, .DropletType:
case .DexcomG5Type, .BubbleType, .MiaoMiaoType, .BluconType, .GNSentryType, .BlueReaderType, .DropletType, .DexcomG4Type:
// cgm's don't receive reading, they send it
break
@ -479,6 +510,21 @@ class BluetoothPeripheralManager: NSObject {
}
}
case .DexcomG4Type:
if let dexcomG4 = bluetoothPeripheral as? DexcomG4 {
if let transmitterId = dexcomG4.blePeripheral.transmitterId, let cgmTransmitterDelegate = cgmTransmitterDelegate {
newTransmitter = CGMG4xDripTransmitter(address: dexcomG4.blePeripheral.address, name: dexcomG4.blePeripheral.name, transmitterID: transmitterId, bluetoothTransmitterDelegate: self, cGMDexcomG4TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate)
} else {
trace("in getBluetoothTransmitter, case DexcomG4Type but transmitterId is nil or cgmTransmitterDelegate is nil, looks like a coding error ", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .error)
}
}
case .BubbleType:
if let bubble = bluetoothPeripheral as? Bubble {
@ -636,6 +682,12 @@ class BluetoothPeripheralManager: NSObject {
if bluetoothTransmitter is CGMDroplet1Transmitter {
return .DropletType
}
case .DexcomG4Type:
if bluetoothTransmitter is CGMG4xDripTransmitter {
return .DexcomG4Type
}
}
}
@ -715,6 +767,14 @@ class BluetoothPeripheralManager: NSObject {
}
return CGMBluconTransmitter(address: nil, name: nil, transmitterID: transmitterId, bluetoothTransmitterDelegate: self, cGMBluconTransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate, timeStampLastBgReading: nil, sensorSerialNumber: nil)
case .DexcomG4Type:
guard let transmitterId = transmitterId, let cgmTransmitterDelegate = cgmTransmitterDelegate else {
fatalError("in createNewTransmitter, type DexcomG4Type, transmitterId is nil or cgmTransmitterDelegate is nil")
}
return CGMG4xDripTransmitter(address: nil, name: nil, transmitterID: transmitterId, bluetoothTransmitterDelegate: self, cGMDexcomG4TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate)
}
@ -915,7 +975,7 @@ class BluetoothPeripheralManager: NSObject {
bluetoothPeripheral.blePeripheral.parameterUpdateNeededAtNextConnect = true
}
case .watlaaMaster, .DexcomG5Type, .BubbleType, .MiaoMiaoType, .BluconType, .GNSentryType, .BlueReaderType, .DropletType:
case .watlaaMaster, .DexcomG5Type, .BubbleType, .MiaoMiaoType, .BluconType, .GNSentryType, .BlueReaderType, .DropletType, .DexcomG4Type:
// none of the observed values needs to be sent to the watlaa
break

View File

@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>3761</string>
<string>3769</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>

View File

@ -0,0 +1,173 @@
import UIKit
class DexcomG4BluetoothPeripheralViewModel {
// MARK: - private properties
/// settings specific for DexcomG4
private enum Settings:Int, CaseIterable {
/// battery level
case batteryLevel = 0
}
/// DexcomG4 settings willb be in section 0 + numberOfGeneralSections
private let sectionNumberForDexcomG4SpecificSettings = 0
/// reference to bluetoothPeripheralManager
private weak var bluetoothPeripheralManager: BluetoothPeripheralManaging?
/// reference to the tableView
private weak var tableView: UITableView?
/// reference to BluetoothPeripheralViewController that will own this WatlaaMasterBluetoothPeripheralViewModel - needed to present stuff etc
private weak var bluetoothPeripheralViewController: BluetoothPeripheralViewController?
/// temporary reference to bluetoothPerpipheral, will be set in configure function.
private var bluetoothPeripheral: BluetoothPeripheral?
/// it's the bluetoothPeripheral as M5Stack
private var DexcomG4: DexcomG4? {
get {
return bluetoothPeripheral as? DexcomG4
}
}
// MARK: - deinit
deinit {
// when closing the viewModel, and if there's still a bluetoothTransmitter existing, then reset the specific delegate to BluetoothPeripheralManager
guard let bluetoothPeripheralManager = bluetoothPeripheralManager else {return}
guard let DexcomG4 = DexcomG4 else {return}
guard let blueToothTransmitter = bluetoothPeripheralManager.getBluetoothTransmitter(for: DexcomG4, createANewOneIfNecesssary: false) else {return}
guard let cGMG4xDripTransmitter = blueToothTransmitter as? CGMG4xDripTransmitter else {return}
cGMG4xDripTransmitter.cGMDexcomG4TransmitterDelegate = bluetoothPeripheralManager as! BluetoothPeripheralManager
}
}
// MARK: - conform to BluetoothPeripheralViewModel
extension DexcomG4BluetoothPeripheralViewModel: BluetoothPeripheralViewModel {
func configure(bluetoothPeripheral: BluetoothPeripheral?, bluetoothPeripheralManager: BluetoothPeripheralManaging, tableView: UITableView, bluetoothPeripheralViewController: BluetoothPeripheralViewController) {
self.bluetoothPeripheralManager = bluetoothPeripheralManager
self.tableView = tableView
self.bluetoothPeripheralViewController = bluetoothPeripheralViewController
self.bluetoothPeripheral = bluetoothPeripheral
if let bluetoothPeripheral = bluetoothPeripheral {
if let dexcomG4 = bluetoothPeripheral as? DexcomG4 {
if let blueToothTransmitter = bluetoothPeripheralManager.getBluetoothTransmitter(for: dexcomG4, createANewOneIfNecesssary: false), let cGMG4xDripTransmitter = blueToothTransmitter as? CGMG4xDripTransmitter {
// set CGMDexcomG4Transmitter delegate to self.
cGMG4xDripTransmitter.cGMDexcomG4TransmitterDelegate = self
}
} else {
fatalError("in DexcomG4BluetoothPeripheralViewModel, configure. bluetoothPeripheral is not DexcomG4")
}
}
}
func screenTitle() -> String {
return BluetoothPeripheralType.DexcomG4Type.rawValue
}
func sectionTitle(forSection section: Int) -> String {
return BluetoothPeripheralType.DexcomG4Type.rawValue
}
func update(cell: UITableViewCell, forRow rawValue: Int, forSection section: Int, for bluetoothPeripheral: BluetoothPeripheral) {
// verify that bluetoothPeripheral is a DexcomG4
guard let DexcomG4 = bluetoothPeripheral as? DexcomG4 else {
fatalError("DexcomG4BluetoothPeripheralViewModel update, bluetoothPeripheral is not DexcomG4")
}
// default value for accessoryView is nil
cell.accessoryView = nil
guard let setting = Settings(rawValue: rawValue) else { fatalError("DexcomG4BluetoothPeripheralViewModel update, unexpected setting") }
switch setting {
case .batteryLevel:
cell.textLabel?.text = Texts_BluetoothPeripheralsView.batteryLevel
if DexcomG4.batteryLevel > 0 {
cell.detailTextLabel?.text = DexcomG4.batteryLevel.description + " %"
} else {
cell.detailTextLabel?.text = ""
}
cell.accessoryType = .none
}
}
func userDidSelectRow(withSettingRawValue rawValue: Int, forSection section: Int, for bluetoothPeripheral: BluetoothPeripheral, bluetoothPeripheralManager: BluetoothPeripheralManaging) -> SettingsSelectedRowAction {
guard let setting = Settings(rawValue: rawValue) else { fatalError("DexcomG4BluetoothPeripheralViewModel userDidSelectRow, unexpected setting") }
switch setting {
case .batteryLevel:
return .nothing
}
}
func numberOfSettings(inSection section: Int) -> Int {
return Settings.allCases.count
}
func numberOfSections() -> Int {
// for the moment only one specific section for DexcomG5
return 1
}
}
// MARK: - conform to CGMDexcomG4TransmitterDelegate
extension DexcomG4BluetoothPeripheralViewModel: CGMDexcomG4TransmitterDelegate {
func received(batteryLevel: Int, from cGMG4xDripTransmitter: CGMG4xDripTransmitter) {
// inform also bluetoothPeripheralManager
(bluetoothPeripheralManager as? CGMDexcomG4TransmitterDelegate)?.received(batteryLevel: batteryLevel, from: cGMG4xDripTransmitter)
// here's the trigger to update the table
reloadRow(row: Settings.batteryLevel.rawValue)
}
private func reloadRow(row: Int) {
if let bluetoothPeripheralViewController = bluetoothPeripheralViewController {
tableView?.reloadRows(at: [IndexPath(row: row, section: bluetoothPeripheralViewController.numberOfGeneralSections() + sectionNumberForDexcomG4SpecificSettings)], with: .none)
}
}
}