Dexcom G4 with xdrip
This commit is contained in:
parent
6a06c650f0
commit
0cc70f2a2d
|
@ -0,0 +1,11 @@
|
|||
import Foundation
|
||||
|
||||
extension DexcomG4: BluetoothPeripheral {
|
||||
|
||||
func bluetoothPeripheralType() -> BluetoothPeripheralType {
|
||||
|
||||
return .DexcomG4Type
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
import Foundation
|
||||
|
||||
protocol CGMDexcomG4TransmitterDelegate: AnyObject {
|
||||
|
||||
/// DexcomG4 is sending batteryLevel
|
||||
func received(batteryLevel: Int, from cGMG4xDripTransmitter: CGMG4xDripTransmitter)
|
||||
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ public class BLEPeripheral: NSManagedObject {
|
|||
self.alias = alias
|
||||
self.parameterUpdateNeededAtNextConnect = false
|
||||
|
||||
webOOPEnabled = false
|
||||
webOOPEnabled = ConstantsLibreOOP.defaultWebOOPEnabled
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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?
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
|
||||
}
|
|
@ -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>
|
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue