Transfer view, change data flow, actors
This commit is contained in:
@ -1,20 +1,36 @@
|
||||
import Foundation
|
||||
|
||||
/*
|
||||
final class TemperatureDataTransfer {
|
||||
|
||||
|
||||
private let startDateOfCurrentTransfer: Date
|
||||
|
||||
private let interval: Int
|
||||
private var interval: TimeInterval {
|
||||
TimeInterval(info.measurementInterval) * dilation
|
||||
}
|
||||
|
||||
private var dataBuffer: Data = Data()
|
||||
|
||||
private(set) var currentByteIndex = 0
|
||||
|
||||
private var info: DeviceInfo
|
||||
|
||||
private let dilation: Double
|
||||
|
||||
private(set) var size: Int
|
||||
var size: Int {
|
||||
info.numberOfRecordedBytes
|
||||
}
|
||||
|
||||
private(set) var blockSize: Int
|
||||
var blockSize: Int {
|
||||
min(50, info.transferBlockSize)
|
||||
}
|
||||
|
||||
private var numberOfRecordingsInCurrentTransfer = 0
|
||||
private var numberOfRecordingsInCurrentTransfer: Int {
|
||||
measurements.count
|
||||
}
|
||||
|
||||
var time: DeviceTime {
|
||||
info.time
|
||||
}
|
||||
|
||||
var measurements: [TemperatureMeasurement] = []
|
||||
|
||||
@ -22,7 +38,7 @@ final class TemperatureDataTransfer {
|
||||
private var lastRecording: TemperatureMeasurement = .init(sensor0: .notFound, sensor1: .notFound, date: .now)
|
||||
|
||||
private var dateOfNextRecording: Date {
|
||||
startDateOfCurrentTransfer.addingTimeInterval(TimeInterval(numberOfRecordingsInCurrentTransfer * interval))
|
||||
startDateOfCurrentTransfer.addingTimeInterval(TimeInterval(numberOfRecordingsInCurrentTransfer) * interval)
|
||||
}
|
||||
|
||||
var unprocessedByteCount: Int {
|
||||
@ -33,39 +49,44 @@ final class TemperatureDataTransfer {
|
||||
size - currentByteIndex
|
||||
}
|
||||
|
||||
init(info: DeviceInfo) {
|
||||
self.interval = info.measurementInterval
|
||||
let recordingTime = info.numberOfStoredMeasurements * info.measurementInterval
|
||||
self.startDateOfCurrentTransfer = info.nextMeasurement.addingTimeInterval(-TimeInterval(recordingTime))
|
||||
self.size = info.numberOfRecordedBytes
|
||||
self.blockSize = info.transferBlockSize
|
||||
init(info: DeviceInfo, previous: DeviceTime?) {
|
||||
let (estimatedStart, dilation) = info.estimatedTimeDilation(to: previous)
|
||||
log.info("Starting transfer")
|
||||
log.info("Estimated start of recording: \(estimatedStart)")
|
||||
log.info("Estimated time dilation: \(dilation)")
|
||||
self.info = info
|
||||
self.dilation = dilation
|
||||
self.startDateOfCurrentTransfer = estimatedStart
|
||||
log.info("True measurement interval: \(interval)")
|
||||
}
|
||||
|
||||
func update(info: DeviceInfo) {
|
||||
self.size = info.numberOfRecordedBytes
|
||||
self.blockSize = info.transferBlockSize
|
||||
self.info = info
|
||||
// Possible bug: Device time updated, but new measurement not transferred
|
||||
// Future transfer will calculate wrong time
|
||||
}
|
||||
|
||||
func nextRequest() -> BluetoothRequest {
|
||||
guard remainingBytesToTransfer > 0 else {
|
||||
return .clearRecordingBuffer(byteCount: size)
|
||||
return .clearRecordingBuffer(byteCount: currentByteIndex)
|
||||
}
|
||||
let chunkSize = min(remainingBytesToTransfer, blockSize)
|
||||
return .getRecordingData(offset: currentByteIndex, count: chunkSize)
|
||||
}
|
||||
|
||||
func add(data: Data, offset: Int, count: Int) {
|
||||
func add(data: Data, offset: Int, count: Int) -> Bool {
|
||||
guard currentByteIndex == offset else {
|
||||
log.warning("Transfer: Discarding \(data.count) bytes at offset \(offset), expected \(currentByteIndex)")
|
||||
return
|
||||
return false
|
||||
}
|
||||
if data.count != count {
|
||||
guard data.count == count else {
|
||||
log.warning("Transfer: Expected \(count) bytes, received only \(data.count)")
|
||||
return false
|
||||
}
|
||||
dataBuffer.append(data)
|
||||
currentByteIndex += data.count
|
||||
processBytes()
|
||||
log.info("Transfer: \(currentByteIndex) bytes (added \(data.count)), \(measurements.count) points")
|
||||
log.info("Transfer: \(currentByteIndex) bytes (added \(data.count))")
|
||||
return true
|
||||
}
|
||||
|
||||
private func processBytes() {
|
||||
@ -76,7 +97,7 @@ final class TemperatureDataTransfer {
|
||||
continue
|
||||
}
|
||||
guard dataBuffer.count >= 2 else {
|
||||
// Wait for more data
|
||||
// Missing data
|
||||
return
|
||||
}
|
||||
let temp0 = TemperatureValue(byte: dataBuffer.removeFirst())
|
||||
@ -85,16 +106,23 @@ final class TemperatureDataTransfer {
|
||||
}
|
||||
}
|
||||
|
||||
func completeTransfer() {
|
||||
func completeTransfer() -> Bool {
|
||||
let emptyIndices = dataBuffer.enumerated().filter { $0.element == 0 }.map { $0.offset }
|
||||
processBytes()
|
||||
if !dataBuffer.isEmpty {
|
||||
guard dataBuffer.isEmpty else {
|
||||
log.warning("\(dataBuffer.count) bytes remaining in transfer buffer")
|
||||
return false
|
||||
}
|
||||
log.info("Transfer: \(currentByteIndex) bytes, \(measurements.count) points")
|
||||
log.info("Transfer complete: \(currentByteIndex) bytes, \(measurements.count) points")
|
||||
log.info("Empty bytes: \(emptyIndices)")
|
||||
if measurements.count != info.numberOfStoredMeasurements {
|
||||
log.warning("Decoded \(measurements.count) points, but only \(info.numberOfStoredMeasurements) recorded")
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private func addRelative(byte: UInt8) {
|
||||
add(sensor0: convertTemp(value: byte >> 4, relativeTo: lastRecording.sensor0),
|
||||
add(sensor0: convertTemp(value: (byte >> 4) & 0x0F, relativeTo: lastRecording.sensor0),
|
||||
sensor1: convertTemp(value: byte & 0x0F, relativeTo: lastRecording.sensor1))
|
||||
}
|
||||
|
||||
@ -103,8 +131,7 @@ final class TemperatureDataTransfer {
|
||||
sensor0: sensor0,
|
||||
sensor1: sensor1,
|
||||
date: dateOfNextRecording)
|
||||
|
||||
numberOfRecordingsInCurrentTransfer += 1
|
||||
|
||||
if measurement.sensor0.isValid {
|
||||
lastRecording.sensor0 = measurement.sensor0
|
||||
}
|
||||
@ -134,3 +161,4 @@ private extension TemperatureValue {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -0,0 +1 @@
|
||||
import Foundation
|
Reference in New Issue
Block a user