rajath_pai

BackgroundCollectingTask

Aug 4th, 2021
738
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import 'dart:convert';
  2.  
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';
  5. import 'package:scoped_model/scoped_model.dart';
  6.  
  7. class DataSample {
  8.   double temperature1;
  9.   double temperature2;
  10.   double waterpHlevel;
  11.   DateTime timestamp;
  12.  
  13.   DataSample({
  14.     required this.temperature1,
  15.     required this.temperature2,
  16.     required this.waterpHlevel,
  17.     required this.timestamp,
  18.   });
  19. }
  20.  
  21. class BackgroundCollectingTask extends Model {
  22.   static BackgroundCollectingTask of(
  23.     BuildContext context, {
  24.     bool rebuildOnChange = false,
  25.   }) =>
  26.       ScopedModel.of<BackgroundCollectingTask>(
  27.         context,
  28.         rebuildOnChange: rebuildOnChange,
  29.       );
  30.  
  31.   final BluetoothConnection _connection;
  32.   List<int> _buffer = List<int>.empty(growable: true);
  33.  
  34.   // @TODO , Such sample collection in real code should be delegated
  35.   // (via `Stream<DataSample>` preferably) and then saved for later
  36.   // displaying on chart (or even stright prepare for displaying).
  37.   // @TODO ? should be shrinked at some point, endless colleting data would cause memory shortage.
  38.   List<DataSample> samples = List<DataSample>.empty(growable: true);
  39.  
  40.   bool inProgress = false;
  41.  
  42.   BackgroundCollectingTask._fromConnection(this._connection) {
  43.     _connection.input!.listen((data) {
  44.       _buffer += data;
  45.  
  46.       while (true) {
  47.         // If there is a sample, and it is full sent
  48.         int index = _buffer.indexOf('t'.codeUnitAt(0));
  49.         if (index >= 0 && _buffer.length - index >= 7) {
  50.           final DataSample sample = DataSample(
  51.               temperature1: (_buffer[index + 1] + _buffer[index + 2] / 100),
  52.               temperature2: (_buffer[index + 3] + _buffer[index + 4] / 100),
  53.               waterpHlevel: (_buffer[index + 5] + _buffer[index + 6] / 100),
  54.               timestamp: DateTime.now());
  55.           _buffer.removeRange(0, index + 7);
  56.  
  57.           samples.add(sample);
  58.           notifyListeners(); // Note: It shouldn't be invoked very often - in this example data comes at every second, but if there would be more data, it should update (including repaint of graphs) in some fixed interval instead of after every sample.
  59.           //print("${sample.timestamp.toString()} -> ${sample.temperature1} / ${sample.temperature2}");
  60.         }
  61.         // Otherwise break
  62.         else {
  63.           break;
  64.         }
  65.       }
  66.     }).onDone(() {
  67.       inProgress = false;
  68.       notifyListeners();
  69.     });
  70.   }
  71.  
  72.   static Future<BackgroundCollectingTask> connect(
  73.       BluetoothDevice server) async {
  74.     final BluetoothConnection connection =
  75.         await BluetoothConnection.toAddress(server.address);
  76.     return BackgroundCollectingTask._fromConnection(connection);
  77.   }
  78.  
  79.   void dispose() {
  80.     _connection.dispose();
  81.   }
  82.  
  83.   Future<void> start() async {
  84.     inProgress = true;
  85.     _buffer.clear();
  86.     samples.clear();
  87.     notifyListeners();
  88.     _connection.output.add(ascii.encode('start'));
  89.     await _connection.output.allSent;
  90.   }
  91.  
  92.   Future<void> cancel() async {
  93.     inProgress = false;
  94.     notifyListeners();
  95.     _connection.output.add(ascii.encode('stop'));
  96.     await _connection.finish();
  97.   }
  98.  
  99.   Future<void> pause() async {
  100.     inProgress = false;
  101.     notifyListeners();
  102.     _connection.output.add(ascii.encode('stop'));
  103.     await _connection.output.allSent;
  104.   }
  105.  
  106.   Future<void> reasume() async {
  107.     inProgress = true;
  108.     notifyListeners();
  109.     _connection.output.add(ascii.encode('start'));
  110.     await _connection.output.allSent;
  111.   }
  112.  
  113.   Iterable<DataSample> getLastOf(Duration duration) {
  114.     DateTime startingTime = DateTime.now().subtract(duration);
  115.     int i = samples.length;
  116.     do {
  117.       i -= 1;
  118.       if (i <= 0) {
  119.         break;
  120.       }
  121.     } while (samples[i].timestamp.isAfter(startingTime));
  122.     return samples.getRange(i, samples.length);
  123.   }
  124. }
RAW Paste Data