GNSentry : correct calculation of reading time, taking into account seconds - also check if rawvalue = 0, GNSentry seems to give only two values != 0

This commit is contained in:
Johan Degraeve 2019-03-18 23:18:43 +01:00
parent 6ccf1bc049
commit f3aa96b09d
3 changed files with 38 additions and 27 deletions

View File

@ -73,7 +73,7 @@ class CGMGNSEntryTransmitter:BluetoothTransmitter, BluetoothTransmitterDelegate,
private var actualDeviceAddress:String? private var actualDeviceAddress:String?
// used in parsing packet // used in parsing packet
private var timeStampLastBgReadingInMinutes:Int private var timeStampLastBgReadingInMinutes:Double
// possible reading errors, as per GNSEntry documentation // possible reading errors, as per GNSEntry documentation
let GNW_BAND_NFC_HW_ERROR = 0 let GNW_BAND_NFC_HW_ERROR = 0
@ -93,7 +93,7 @@ class CGMGNSEntryTransmitter:BluetoothTransmitter, BluetoothTransmitterDelegate,
} }
//initialize timeStampLastBgReading //initialize timeStampLastBgReading
self.timeStampLastBgReadingInMinutes = Int(timeStampLastBgReading.toMillisecondsAsDouble()/1000/60) self.timeStampLastBgReadingInMinutes = timeStampLastBgReading.toMillisecondsAsDouble()/1000/60
// initialize - CBUUID_Receive_Authentication.rawValue and CBUUID_Write_Control.rawValue will probably not be used in the superclass, also not the CBUUID_Service // initialize - CBUUID_Receive_Authentication.rawValue and CBUUID_Write_Control.rawValue will probably not be used in the superclass, also not the CBUUID_Service
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: nil, servicesCBUUIDs: [CBUUID(string: CBUUID_GNWService), CBUUID(string: CBUUID_BatteryService), CBUUID(string: CBUUID_DeviceInformationService)], CBUUID_ReceiveCharacteristic: CBUUID_Characteristic_UUID.CBUUID_GNW_Notify.rawValue, CBUUID_WriteCharacteristic: CBUUID_Characteristic_UUID.CBUUID_GNW_Write.rawValue) super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: nil, servicesCBUUIDs: [CBUUID(string: CBUUID_GNWService), CBUUID(string: CBUUID_BatteryService), CBUUID(string: CBUUID_DeviceInformationService)], CBUUID_ReceiveCharacteristic: CBUUID_Characteristic_UUID.CBUUID_GNW_Notify.rawValue, CBUUID_WriteCharacteristic: CBUUID_Characteristic_UUID.CBUUID_GNW_Write.rawValue)
@ -135,10 +135,6 @@ class CGMGNSEntryTransmitter:BluetoothTransmitter, BluetoothTransmitterDelegate,
if let receivedCharacteristic = CBUUID_Characteristic_UUID(rawValue: characteristic.uuid.uuidString), let value = characteristic.value { if let receivedCharacteristic = CBUUID_Characteristic_UUID(rawValue: characteristic.uuid.uuidString), let value = characteristic.value {
// convert to hex string, GNS entry seems to use hex string in many cases
let dataAsString = value.hexEncodedString()
os_log(" received value : %{public}@", log: log, type: .info, dataAsString)
switch receivedCharacteristic { switch receivedCharacteristic {
case .CBUUID_SerialNumber: case .CBUUID_SerialNumber:
@ -148,6 +144,7 @@ class CGMGNSEntryTransmitter:BluetoothTransmitter, BluetoothTransmitterDelegate,
case .CBUUID_Bootloader: case .CBUUID_Bootloader:
break break
case .CBUUID_BatteryLevel: case .CBUUID_BatteryLevel:
let dataAsString = value.hexEncodedString()
if let batteryLevel = Int(dataAsString, radix: 16) { if let batteryLevel = Int(dataAsString, radix: 16) {
var emptyArray: [RawGlucoseData] = [] var emptyArray: [RawGlucoseData] = []
cgmTransmitterDelegate?.cgmTransmitterInfoReceived(glucoseData: &emptyArray, transmitterBatteryInfo: TransmitterBatteryInfo.percentage(percentage: batteryLevel), sensorState: nil, sensorTimeInMinutes: nil, firmware: nil, hardware: nil) cgmTransmitterDelegate?.cgmTransmitterInfoReceived(glucoseData: &emptyArray, transmitterBatteryInfo: TransmitterBatteryInfo.percentage(percentage: batteryLevel), sensorState: nil, sensorTimeInMinutes: nil, firmware: nil, hardware: nil)
@ -158,10 +155,13 @@ class CGMGNSEntryTransmitter:BluetoothTransmitter, BluetoothTransmitterDelegate,
break break
case .CBUUID_GNW_Notify: case .CBUUID_GNW_Notify:
// decode as explained in GNSEntry documentation // decode as explained in GNSEntry documentation
var arrayData = XORENC(inD: [UInt8](value)) var valueDecoded = XORENC(inD: [UInt8](value))
let valueDecodedAsHexString = Data(valueDecoded).hexEncodedString()
os_log(" in peripheralDidUpdateValueFor, GNW Notify with hex value = %{public}@", log: log, type: .error , valueDecodedAsHexString)
// reading status, as per GNSEntry documentation // reading status, as per GNSEntry documentation
let readingStatus = getIntAtPosition(numberOfBytes: 1, position: 0, data: &arrayData) let readingStatus = getIntAtPosition(numberOfBytes: 1, position: 0, data: &valueDecoded)
if readingStatus == GNW_BAND_NFC_HW_ERROR || readingStatus == GNW_BAND_NFC_READING_ERROR { if readingStatus == GNW_BAND_NFC_HW_ERROR || readingStatus == GNW_BAND_NFC_READING_ERROR {
os_log(" in peripheralDidUpdateValueFor, readingStatus is not OK", log: log, type: .info) os_log(" in peripheralDidUpdateValueFor, readingStatus is not OK", log: log, type: .info)
@ -169,44 +169,52 @@ class CGMGNSEntryTransmitter:BluetoothTransmitter, BluetoothTransmitterDelegate,
} else { } else {
// get sensor elapsed time and initialize sensorStartTimeInMilliseconds // get sensor elapsed time and initialize sensorStartTimeInMilliseconds
let sensorElapsedTimeInMinutes = getIntAtPosition(numberOfBytes: 2, position: 3, data: &arrayData) let sensorElapsedTimeInMinutes = getIntAtPosition(numberOfBytes: 2, position: 3, data: &valueDecoded)
// we will add the most recent readings, but then we'll only add the readings that are at least 5 minutes apart (giving 10 seconds spare) // we will add the most recent readings, but then we'll only add the readings that are at least 5 minutes apart (giving 10 seconds spare)
// for that variable timeStampLastAddedGlucoseData is used. It's initially set to now + 5 minutes // for that variable timeStampLastAddedGlucoseData is used. It's initially set to now + 5 minutes
let currentTimeInMinutes:Int = Int(Date().toMillisecondsAsDouble()/1000/60) let currentTimeInMinutes:Double = Date().toMillisecondsAsDouble()/1000/60
var timeStampLastAddedGlucoseDataInMinutes:Int = currentTimeInMinutes + 5 var timeStampLastAddedGlucoseDataInMinutes:Double = currentTimeInMinutes + 5.0
// read sensor status // read sensor status
let sensorStatus = SensorState(stateByte: UInt8(getIntAtPosition(numberOfBytes: 1, position: 5, data: &arrayData))) let sensorStatus = SensorState(stateByte: UInt8(getIntAtPosition(numberOfBytes: 1, position: 5, data: &valueDecoded)))
// initialize empty array of bgreadings // initialize empty array of bgreadings
var readings:Array<RawGlucoseData> = [] var readings:Array<RawGlucoseData> = []
// amountofReadingsPerMinute = how many readings per minute - see example code GNSEntry, if only one packet of 20 bytes transmitted, then only 5 readings 1 minute seperated // amountofReadingsPerMinute = how many readings per minute - see example code GNSEntry, if only one packet of 20 bytes transmitted, then only 5 readings 1 minute seperated
var amountOfPerMinuteReadings = 5 var amountOfPerMinuteReadings:Double = 5.0
var amountOfPer15MinuteReadings = 0 var amountOfPer15MinuteReadings:Double = 0.0
if arrayData.count > 20 { if valueDecoded.count > 20 {
amountOfPerMinuteReadings = 17 amountOfPerMinuteReadings = 17.0
amountOfPer15MinuteReadings = 33 amountOfPer15MinuteReadings = 33.0
} }
// variable to loop through the readdings // variable to loop through the readdings
var i = 0 var i = 0.0
loop: while 7 + i * 2 < arrayData.count - 1 && i < amountOfPerMinuteReadings + amountOfPer15MinuteReadings { loop: while Int(7.0 + i * 2.0) < valueDecoded.count - 1 && i < amountOfPerMinuteReadings + amountOfPer15MinuteReadings {
// timestamp of the reading in minutes, counting from 1 1 1970 // timestamp of the reading in minutes, counting from 1 1 1970
let readingTimeStampInMinutes = currentTimeInMinutes - (i < amountOfPerMinuteReadings ? i : i * 15) let readingTimeStampInMinutes:Double = currentTimeInMinutes - (i < amountOfPerMinuteReadings ? i : i * 15.0)
debuglogging("new reading with readingTimeStampInMinutes " + Double(readingTimeStampInMinutes * 60 * 1000).asTimeStampInMilliSecondsToString())
// get the reading value (mgdl) // get the reading value (mgdl)
let readingValueInMgDl = getIntAtPosition(numberOfBytes: 2, position: 7 + i * 2, data: &arrayData) let readingValueInMgDl = getIntAtPosition(numberOfBytes: 2, position: Int(7 + i * 2), data: &valueDecoded)
debuglogging(" with readingValueInMgDl = " + readingValueInMgDl.description)
//new reading should be at least 30 seconds younger than timeStampLastBgReadingStoredInDatabase //new reading should be at least 30 seconds younger than timeStampLastBgReadingStoredInDatabase
if readingTimeStampInMinutes > ((timeStampLastBgReadingInMinutes * 2) + 1)/2 { if readingTimeStampInMinutes > ((timeStampLastBgReadingInMinutes * 2) + 1)/2 {
// sometimes 0 values are received, skip those
if readingValueInMgDl > 0 {
debuglogging(" readingTimeStampInMinutes * 60 * 1000 = " + ((Int)(readingTimeStampInMinutes * 60 * 1000)).description)
debuglogging(" timeStampLastAddedGlucoseDataInMinutes * 60 * 1000 = " + (Int)(timeStampLastAddedGlucoseDataInMinutes * 60 * 1000).description)
debuglogging(" timeStampLastAddedGlucoseDataInMinutes * 60 * 1000 - (5 * 60 * 1000 - 10000) = " + (Int)(timeStampLastAddedGlucoseDataInMinutes * 60 * 1000 - (5 * 60 * 1000 - 10000)).description)
if readingTimeStampInMinutes * 60 * 1000 < timeStampLastAddedGlucoseDataInMinutes * 60 * 1000 - (5 * 60 * 1000 - 10000) { if readingTimeStampInMinutes * 60 * 1000 < timeStampLastAddedGlucoseDataInMinutes * 60 * 1000 - (5 * 60 * 1000 - 10000) {
let glucoseData = RawGlucoseData(timeStamp: Date(timeIntervalSince1970: Double(readingTimeStampInMinutes) * 60.0), glucoseLevelRaw: Double(readingValueInMgDl) * Constants.Libre.libreMultiplier) let glucoseData = RawGlucoseData(timeStamp: Date(timeIntervalSince1970: Double(readingTimeStampInMinutes) * 60.0), glucoseLevelRaw: Double(readingValueInMgDl) * Constants.Libre.libreMultiplier)
readings.append(glucoseData) readings.append(glucoseData)
timeStampLastAddedGlucoseDataInMinutes = readingTimeStampInMinutes timeStampLastAddedGlucoseDataInMinutes = readingTimeStampInMinutes
} }
}
} else { } else {
break loop break loop
} }
@ -219,7 +227,7 @@ class CGMGNSEntryTransmitter:BluetoothTransmitter, BluetoothTransmitterDelegate,
//set timeStampLastBgReading to timestamp of latest reading in the response so that next time we parse only the more recent readings //set timeStampLastBgReading to timestamp of latest reading in the response so that next time we parse only the more recent readings
if readings.count > 0 { if readings.count > 0 {
timeStampLastBgReadingInMinutes = Int(readings[0].timeStamp.toMillisecondsAsDouble()/1000/60) timeStampLastBgReadingInMinutes = readings[0].timeStamp.toMillisecondsAsDouble()/1000/60
} }
} }
} }

View File

@ -8,6 +8,7 @@ struct RawGlucoseData {
var glucoseLevelFiltered:Double var glucoseLevelFiltered:Double
init(timeStamp:Date, glucoseLevelRaw:Double, glucoseLevelFiltered:Double) { init(timeStamp:Date, glucoseLevelRaw:Double, glucoseLevelFiltered:Double) {
debuglogging("in init glucoselevelRaw, timestamp = " + timeStamp.toMillisecondsAsDouble().asTimeStampInMilliSecondsToString())
self.timeStamp = timeStamp self.timeStamp = timeStamp
self.glucoseLevelRaw = glucoseLevelRaw self.glucoseLevelRaw = glucoseLevelRaw
self.glucoseLevelFiltered = glucoseLevelFiltered self.glucoseLevelFiltered = glucoseLevelFiltered

View File

@ -360,6 +360,8 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
os_log(" Call discovercharacteristics for service with uuid %{public}@", log: log, type: .info, String(describing: service.uuid)) os_log(" Call discovercharacteristics for service with uuid %{public}@", log: log, type: .info, String(describing: service.uuid))
peripheral.discoverCharacteristics(nil, for: service) peripheral.discoverCharacteristics(nil, for: service)
} }
} else {
disconnect()
} }
} }