attach method
Attach this RxAutoExpResult to the Frame's dataResponse characteristic stream.
Implementation
Stream<AutoExpResult> attach(Stream<List<int>> dataResponse) {
// TODO check for illegal state - attach() already called on this RxAutoExpResult etc?
// might be possible though after a clean close(), do I want to prevent it?
// the subscription to the underlying data stream
StreamSubscription<List<int>>? dataResponseSubs;
// Our stream controller that transforms/accumulates the raw tap events into multi-taps
_controller = StreamController();
_controller!.onListen = () {
dataResponseSubs = dataResponse
.where((data) => data[0] == autoExpFlag)
.listen((data) {
// parse the metering data from the raw data
_log.finer('auto exposure result detected');
// Ensure the data length is sufficient
if (data.length < 65) {
_log.warning('Insufficient data length for AutoExpResult: ${data.length}');
return;
}
// Extract the relevant data (bytes 1 to 65)
List<int> relevantData = data.sublist(1, 65);
// Create a ByteData object from the relevant data
ByteData byteData = ByteData.sublistView(Uint8List.fromList(relevantData));
// Unpack the data as 16 float32 values
List<double> unpacked = List.generate(16, (i) => byteData.getFloat32(i * 4, Endian.little));
_controller!.add(AutoExpResult(
error: unpacked[0],
shutter: unpacked[1],
analogGain: unpacked[2],
redGain: unpacked[3],
greenGain: unpacked[4],
blueGain: unpacked[5],
brightness: Brightness(
centerWeightedAverage: unpacked[6],
scene: unpacked[7],
matrix: Matrix(
r: unpacked[8],
g: unpacked[9],
b: unpacked[10],
average: unpacked[11],
),
spot: Spot(
r: unpacked[12],
g: unpacked[13],
b: unpacked[14],
average: unpacked[15],
),
),
));
}, onDone: _controller!.close, onError: _controller!.addError);
_log.fine('AutoExposureResultDataResponse stream subscribed');
};
_controller!.onCancel = () {
_log.fine('AutoExposureResultDataResponse stream unsubscribed');
dataResponseSubs?.cancel();
_controller!.close();
};
return _controller!.stream;
}