Watlaa connection, master mode (ie watlaa is master) - receives Libre packets and watlaa battery level
This is a test version To setup Watlaa : - go to settings tab, select transmitter type Watlaa - go back to home screen - click transmitter - click start sensor and start the sensor - then go to the bluetooth tab (the second tab) - click the + - select watlaa - select watlaa master - scan - click 'done' xdrip should now receive the libre packets, you should get a calibration request
This commit is contained in:
parent
586737fe13
commit
2ec60c502f
|
@ -69,6 +69,8 @@
|
|||
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 */; };
|
||||
|
@ -328,6 +330,8 @@
|
|||
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>"; };
|
||||
|
@ -904,6 +908,8 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
F830991F23C291E2005741DF /* WatlaaBluetoothTransmitterMaster.swift */,
|
||||
F830992D23C7D756005741DF /* WatlaaBluetoothTransmitterMaster+CGMTransmitter.swift */,
|
||||
F830992F23C928E0005741DF /* WatlaaBluetoothTransmitterDelegate.swift */,
|
||||
);
|
||||
path = watlaa;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1548,10 +1554,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>";
|
||||
|
@ -1923,6 +1929,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 */,
|
||||
|
@ -1930,6 +1937,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 */,
|
||||
|
|
|
@ -14,7 +14,7 @@ enum BluetoothPeripheralType: String, CaseIterable {
|
|||
case M5StickCType = "M5StickC"
|
||||
|
||||
/// watlaa master
|
||||
case watlaaMaster = "watlaaMaster"
|
||||
case watlaaMaster = "Watlaa master"
|
||||
|
||||
/// - returns: the BluetoothPeripheralViewModel
|
||||
func viewModel() -> BluetoothPeripheralViewModel {
|
||||
|
|
|
@ -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?
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -398,10 +398,8 @@ final class M5StackBluetoothTransmitter: BluetoothTransmitter {
|
|||
case .readBatteryLevelRx:
|
||||
|
||||
guard value.count >= 2 else {
|
||||
|
||||
trace(" value length should be minimum 2", log: log, 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
|
||||
}
|
||||
|
||||
}
|
|
@ -2,7 +2,7 @@ import Foundation
|
|||
import os
|
||||
import CoreBluetooth
|
||||
|
||||
class WatlaaBluetoothTransmitterMaster: BluetoothTransmitter {
|
||||
final class WatlaaBluetoothTransmitterMaster: BluetoothTransmitter {
|
||||
|
||||
// MARK: UUID's
|
||||
|
||||
|
@ -16,7 +16,7 @@ class WatlaaBluetoothTransmitterMaster: BluetoothTransmitter {
|
|||
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 {
|
||||
private enum CBUUID_Characteristic_UUID:String, CustomStringConvertible, CaseIterable {
|
||||
|
||||
/// Raw data characteristic
|
||||
case CBUUID_RawData_Characteristic = "00001011-1212-EFDE-0137-875F45AC0113"
|
||||
|
@ -76,32 +76,137 @@ class WatlaaBluetoothTransmitterMaster: BluetoothTransmitter {
|
|||
/// 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: M5StackBluetoothTransmitterDelegate, bluetoothPeripheralType: BluetoothPeripheralType) {
|
||||
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)
|
||||
|
||||
//assign CGMTransmitterDelegate
|
||||
self.cgmTransmitterDelegate = cgmTransmitterDelegate
|
||||
}
|
||||
|
||||
/// 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()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -127,6 +232,17 @@ class WatlaaBluetoothTransmitterMaster: BluetoothTransmitter {
|
|||
|
||||
private func handleUpdateValueFor_BatteryLevel_Characteristic(value: Data) {
|
||||
|
||||
guard value.count >= 1 else {
|
||||
trace(" value length should be minimum 1", log: log, 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) {
|
||||
|
@ -135,23 +251,45 @@ class WatlaaBluetoothTransmitterMaster: BluetoothTransmitter {
|
|||
|
||||
// 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, 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 characteristic_UUID = CBUUID_Characteristic_UUID(rawValue: characteristic.uuid.uuidString) else {
|
||||
guard let receivedCharacteristic = receivedCharacteristicUUIDToCharacteristic(characteristicUUID: characteristic.uuid.uuidString) else {
|
||||
trace("in peripheralDidUpdateValueFor, unknown characteristic received with uuid = %{public}@", log: log, type: .error, characteristic.uuid.uuidString)
|
||||
return
|
||||
}
|
||||
|
||||
trace("in peripheralDidUpdateValueFor, characteristic uuid = %{public}@", log: log, type: .info, characteristic_UUID.description)
|
||||
trace("in peripheralDidUpdateValueFor, characteristic uuid = %{public}@", log: log, type: .info, receivedCharacteristic.description)
|
||||
|
||||
guard let value = characteristic.value else {return}
|
||||
|
||||
debuglogging("Received value from Watlaa : " + value.hexEncodedString())
|
||||
|
||||
switch characteristic_UUID {
|
||||
switch receivedCharacteristic {
|
||||
|
||||
case .CBUUID_RawData_Characteristic:
|
||||
handleUpdateValueFor_RawData_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
|
||||
|
|
|
@ -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?) {
|
||||
|
|
|
@ -5,6 +5,9 @@ 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:
|
||||
|
|
|
@ -40,12 +40,17 @@ 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
|
||||
/// 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, cgmTransmitterDelegate: CGMTransmitterDelegate) {
|
||||
/// - parameters:
|
||||
/// - onCGMTransmitterCreation : to be called when cgmtransmitter is created
|
||||
init(coreDataManager: CoreDataManager, cgmTransmitterDelegate: CGMTransmitterDelegate, onCGMTransmitterCreation: @escaping (CGMTransmitter?) -> ()) {
|
||||
|
||||
// initialize properties
|
||||
self.coreDataManager = coreDataManager
|
||||
|
@ -53,6 +58,7 @@ class BluetoothPeripheralManager: NSObject {
|
|||
self.bgReadingsAccessor = BgReadingsAccessor(coreDataManager: coreDataManager)
|
||||
self.watlaaAccessor = WatlaaAccessor(coreDataManager: coreDataManager)
|
||||
self.cgmTransmitterDelegate = cgmTransmitterDelegate
|
||||
self.onCGMTransmitterCreation = onCGMTransmitterCreation
|
||||
|
||||
super.init()
|
||||
|
||||
|
@ -187,6 +193,92 @@ 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)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// send all parameters to m5Stack
|
||||
/// - parameters:
|
||||
/// - to : m5StackBluetoothTransmitter to send all parameters
|
||||
/// - returns:
|
||||
/// successfully written all parameters or not
|
||||
private func sendAllParametersToM5Stack(to m5StackBluetoothTransmitter : M5StackBluetoothTransmitter) -> Bool {
|
||||
|
||||
// should find the m5StackBluetoothTransmitter in bluetoothTransmitters and it should be an M5Stack
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: m5StackBluetoothTransmitter), let m5Stack = bluetoothPeripherals[index] as? M5Stack else {return false}
|
||||
|
||||
// M5Stack must be ready to receive data
|
||||
guard m5StackBluetoothTransmitter.isReadyToReceiveData else {
|
||||
trace("in sendAllParameters, bluetoothTransmitter is not ready to receive data", log: self.log, type: .info)
|
||||
return false
|
||||
}
|
||||
|
||||
// initialise returnValue, result
|
||||
var success = true
|
||||
|
||||
// send bloodglucoseunit
|
||||
if !m5StackBluetoothTransmitter.writeBloodGlucoseUnit(isMgDl: UserDefaults.standard.bloodGlucoseUnitIsMgDl) {success = false}
|
||||
|
||||
// send textColor
|
||||
if !m5StackBluetoothTransmitter.writeTextColor(textColor: M5StackColor(forUInt16: UInt16(m5Stack.textcolor)) ?? UserDefaults.standard.m5StackTextColor ?? ConstantsM5Stack.defaultTextColor) {success = false}
|
||||
|
||||
// send backGroundColor
|
||||
if !m5StackBluetoothTransmitter.writeBackGroundColor(backGroundColor: M5StackColor(forUInt16: UInt16(m5Stack.backGroundColor)) ?? ConstantsM5Stack.defaultBackGroundColor ) {success = false}
|
||||
|
||||
// send rotation
|
||||
if !m5StackBluetoothTransmitter.writeRotation(rotation: Int(m5Stack.rotation)) {success = false}
|
||||
|
||||
// send connectToWiFi
|
||||
if !m5StackBluetoothTransmitter.writeConnectToWiFi(connect: m5Stack.connectToWiFi) {success = false}
|
||||
|
||||
// send WiFiSSID's
|
||||
if let wifiName = UserDefaults.standard.m5StackWiFiName1 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiName(name: wifiName, number: 1) {success = false}
|
||||
}
|
||||
if let wifiName = UserDefaults.standard.m5StackWiFiName2 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiName(name: wifiName, number: 2) {success = false}
|
||||
}
|
||||
if let wifiName = UserDefaults.standard.m5StackWiFiName3 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiName(name: wifiName, number: 3) {success = false}
|
||||
}
|
||||
|
||||
// send WiFiPasswords
|
||||
if let wifiPassword = UserDefaults.standard.m5StackWiFiPassword1 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiPassword(password: wifiPassword, number: 1) {success = false}
|
||||
}
|
||||
if let wifiPassword = UserDefaults.standard.m5StackWiFiPassword2 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiPassword(password: wifiPassword, number: 2) {success = false}
|
||||
}
|
||||
if let wifiPassword = UserDefaults.standard.m5StackWiFiPassword3 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiPassword(password: wifiPassword, number: 3) {success = false}
|
||||
}
|
||||
|
||||
// send nightscout url
|
||||
if let url = UserDefaults.standard.nightScoutUrl {
|
||||
if !m5StackBluetoothTransmitter.writeNightScoutUrl(url: url) {success = false}
|
||||
}
|
||||
|
||||
// send nightscout token
|
||||
if let token = UserDefaults.standard.nightScoutAPIKey {
|
||||
if !m5StackBluetoothTransmitter.writeNightScoutAPIKey(apiKey: token) {success = false}
|
||||
}
|
||||
|
||||
// return success
|
||||
return success
|
||||
}
|
||||
|
||||
/// when user changes M5Stack related settings, then the transmitter need to get that info, add observers
|
||||
private func addObservers() {
|
||||
|
||||
|
@ -214,7 +306,7 @@ class BluetoothPeripheralManager: NSObject {
|
|||
|
||||
if let bluetoothTransmitter = getBluetoothTransmitter(for: bluetoothPeripheral, createANewOneIfNecesssary: false) {
|
||||
|
||||
bluetoothTransmitter.disconnect(reconnectAfterDisconnect: false)
|
||||
_ = bluetoothTransmitter.disconnect(reconnectAfterDisconnect: false)
|
||||
|
||||
}
|
||||
|
||||
|
@ -376,9 +468,7 @@ class BluetoothPeripheralManager: NSObject {
|
|||
|
||||
}
|
||||
|
||||
// MARK: - extensions
|
||||
|
||||
// MARK: extension BluetoothPeripheralManaging
|
||||
// MARK: - conform to BluetoothPeripheralManaging
|
||||
|
||||
extension BluetoothPeripheralManager: BluetoothPeripheralManaging {
|
||||
|
||||
|
@ -504,6 +594,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
|
||||
|
||||
|
@ -546,6 +639,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
|
||||
|
||||
}
|
||||
|
@ -553,12 +649,17 @@ extension BluetoothPeripheralManager: BluetoothPeripheralManaging {
|
|||
|
||||
}
|
||||
|
||||
// MARK: extension M5StackBluetoothDelegate
|
||||
// MARK: - conform to BluetoothTransmitterDelegate
|
||||
|
||||
extension BluetoothPeripheralManager: BluetoothTransmitterDelegate {
|
||||
|
||||
func didConnectTo(bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
// temporary,
|
||||
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: self.log, type: .info)
|
||||
|
@ -635,7 +736,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 {
|
||||
|
||||
|
@ -722,7 +844,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 {
|
||||
|
@ -761,77 +883,6 @@ extension BluetoothPeripheralManager: M5StackBluetoothTransmitterDelegate {
|
|||
|
||||
}
|
||||
|
||||
// MARK: private functions related to M5Stack
|
||||
|
||||
/// send all parameters to m5Stack
|
||||
/// - parameters:
|
||||
/// - to : m5StackBluetoothTransmitter to send all parameters
|
||||
/// - returns:
|
||||
/// successfully written all parameters or not
|
||||
private func sendAllParametersToM5Stack(to m5StackBluetoothTransmitter : M5StackBluetoothTransmitter) -> Bool {
|
||||
|
||||
// should find the m5StackBluetoothTransmitter in bluetoothTransmitters and it should be an M5Stack
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: m5StackBluetoothTransmitter), let m5Stack = bluetoothPeripherals[index] as? M5Stack else {return false}
|
||||
|
||||
// M5Stack must be ready to receive data
|
||||
guard m5StackBluetoothTransmitter.isReadyToReceiveData else {
|
||||
trace("in sendAllParameters, bluetoothTransmitter is not ready to receive data", log: self.log, type: .info)
|
||||
return false
|
||||
}
|
||||
|
||||
// initialise returnValue, result
|
||||
var success = true
|
||||
|
||||
// send bloodglucoseunit
|
||||
if !m5StackBluetoothTransmitter.writeBloodGlucoseUnit(isMgDl: UserDefaults.standard.bloodGlucoseUnitIsMgDl) {success = false}
|
||||
|
||||
// send textColor
|
||||
if !m5StackBluetoothTransmitter.writeTextColor(textColor: M5StackColor(forUInt16: UInt16(m5Stack.textcolor)) ?? UserDefaults.standard.m5StackTextColor ?? ConstantsM5Stack.defaultTextColor) {success = false}
|
||||
|
||||
// send backGroundColor
|
||||
if !m5StackBluetoothTransmitter.writeBackGroundColor(backGroundColor: M5StackColor(forUInt16: UInt16(m5Stack.backGroundColor)) ?? ConstantsM5Stack.defaultBackGroundColor ) {success = false}
|
||||
|
||||
// send rotation
|
||||
if !m5StackBluetoothTransmitter.writeRotation(rotation: Int(m5Stack.rotation)) {success = false}
|
||||
|
||||
// send connectToWiFi
|
||||
if !m5StackBluetoothTransmitter.writeConnectToWiFi(connect: m5Stack.connectToWiFi) {success = false}
|
||||
|
||||
// send WiFiSSID's
|
||||
if let wifiName = UserDefaults.standard.m5StackWiFiName1 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiName(name: wifiName, number: 1) {success = false}
|
||||
}
|
||||
if let wifiName = UserDefaults.standard.m5StackWiFiName2 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiName(name: wifiName, number: 2) {success = false}
|
||||
}
|
||||
if let wifiName = UserDefaults.standard.m5StackWiFiName3 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiName(name: wifiName, number: 3) {success = false}
|
||||
}
|
||||
|
||||
// send WiFiPasswords
|
||||
if let wifiPassword = UserDefaults.standard.m5StackWiFiPassword1 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiPassword(password: wifiPassword, number: 1) {success = false}
|
||||
}
|
||||
if let wifiPassword = UserDefaults.standard.m5StackWiFiPassword2 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiPassword(password: wifiPassword, number: 2) {success = false}
|
||||
}
|
||||
if let wifiPassword = UserDefaults.standard.m5StackWiFiPassword3 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiPassword(password: wifiPassword, number: 3) {success = false}
|
||||
}
|
||||
|
||||
// send nightscout url
|
||||
if let url = UserDefaults.standard.nightScoutUrl {
|
||||
if !m5StackBluetoothTransmitter.writeNightScoutUrl(url: url) {success = false}
|
||||
}
|
||||
|
||||
// send nightscout token
|
||||
if let token = UserDefaults.standard.nightScoutAPIKey {
|
||||
if !m5StackBluetoothTransmitter.writeNightScoutAPIKey(apiKey: token) {success = false}
|
||||
}
|
||||
|
||||
// return success
|
||||
return success
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>3179</string>
|
||||
<string>3233</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -5,6 +5,14 @@ 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?
|
||||
|
||||
|
@ -19,7 +27,7 @@ class WatlaaMasterBluetoothPeripheralViewModel {
|
|||
|
||||
}
|
||||
|
||||
// MARK: - extension BluetoothPeripheralViewModelProtocol
|
||||
// MARK: - conform to BluetoothPeripheralViewModel
|
||||
|
||||
extension WatlaaMasterBluetoothPeripheralViewModel: BluetoothPeripheralViewModel {
|
||||
|
||||
|
@ -37,6 +45,13 @@ extension WatlaaMasterBluetoothPeripheralViewModel: BluetoothPeripheralViewModel
|
|||
|
||||
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()
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -51,19 +66,66 @@ extension WatlaaMasterBluetoothPeripheralViewModel: BluetoothPeripheralViewModel
|
|||
|
||||
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 0
|
||||
return WatlaaSetting.allCases.count
|
||||
}
|
||||
|
||||
func numberOfSections() -> Int {
|
||||
// for the moment only one specific section for watlaa
|
||||
return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
func storeTempValues(from bluetoothPeripheral: BluetoothPeripheral) {
|
||||
|
@ -75,7 +137,7 @@ extension WatlaaMasterBluetoothPeripheralViewModel: BluetoothPeripheralViewModel
|
|||
|
||||
}
|
||||
|
||||
// MARK: - extension BluetoothTransmitterDelegate
|
||||
// MARK: - conform to BluetoothTransmitterDelegate
|
||||
|
||||
extension WatlaaMasterBluetoothPeripheralViewModel: BluetoothTransmitterDelegate {
|
||||
|
||||
|
@ -94,3 +156,19 @@ extension WatlaaMasterBluetoothPeripheralViewModel: BluetoothTransmitterDelegate
|
|||
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -406,7 +406,12 @@ final class RootViewController: UIViewController {
|
|||
})
|
||||
|
||||
// setup bluetoothPeripheralManager
|
||||
bluetoothPeripheralManager = BluetoothPeripheralManager(coreDataManager: coreDataManager, cgmTransmitterDelegate: self)
|
||||
bluetoothPeripheralManager = BluetoothPeripheralManager(coreDataManager: coreDataManager, cgmTransmitterDelegate: self, onCGMTransmitterCreation: {
|
||||
(cgmTransmitter: CGMTransmitter?) in
|
||||
|
||||
self.cgmTransmitter = cgmTransmitter
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
@ -811,6 +816,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
|
||||
|
@ -818,7 +827,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)
|
||||
}
|
||||
|
@ -1318,6 +1327,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