attach method

Stream<IMUData> attach(
  1. Stream<List<int>> dataResponse
)

Attach this RxIMU to the Frame's dataResponse characteristic stream.

Implementation

Stream<IMUData> attach(Stream<List<int>> dataResponse) {
  // TODO check for illegal state - attach() already called on this RxIMU 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 the dataResponse elements into IMUData events
  _controller = StreamController();

  _controller!.onListen = () {
    dataResponseSubs = dataResponse
      .where((data) => data[0] == imuFlag)
      .listen((data) {
        // data structure: [flag, ?, float, float, float, float, float, float]
        // offsets: 0, 1, 2..5, 6..9, 10..13, 14..17, 18..21, 22..25
        // total length should be at least 2 + 6*4 = 26 bytes.

        if (data.length < 26) {
           // Not enough data for 6 floats + header
           return;
        }

        final byteData = ByteData.sublistView(Uint8List.fromList(data));

        // Read 6 32-bit little-endian floats starting at offset 2
        double cX = byteData.getFloat32(2, Endian.little);
        double cY = byteData.getFloat32(6, Endian.little);
        double cZ = byteData.getFloat32(10, Endian.little);
        double aX = byteData.getFloat32(14, Endian.little);
        double aY = byteData.getFloat32(18, Endian.little);
        double aZ = byteData.getFloat32(22, Endian.little);

        // Get raw values
        var rawCompass = (cX, cY, cZ);
        var rawAccel = (aX, aY, aZ);

        // Add to buffers
        _compassBuffer.add(rawCompass);
        _accelBuffer.add(rawAccel);

        _controller!.add(IMUData(
          compass: _compassBuffer.average,
          accel: _accelBuffer.average,
          raw: IMURawData(
            compass: rawCompass,
            accel: rawAccel,
          ),
        ));

    }, onDone: _controller!.close, onError: _controller!.addError);
    _log.fine('ImuDataResponse stream subscribed');
  };

  _controller!.onCancel = () {
    _log.fine('ImuDataResponse stream unsubscribed');
    dataResponseSubs?.cancel();
    _controller!.close();
  };

  return _controller!.stream;
}