Untitled
unknown
plain_text
2 years ago
5.6 kB
10
Indexable
import 'dart:developer';
import 'dart:ffi';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:self_science_station/model/metric_model.dart';
import 'package:self_science_station/model/sensor_model.dart';
import 'package:self_science_station/sensor/sensorInstance.dart';
import 'package:self_science_station/utils/utils.dart';
import 'package:self_science_station/sensor/polar_api.dart';
import 'package:polar/polar.dart';
// TODO create a custom type that has fields:
// - SensorTypeModel
// - SensorState
// - Function handlers for state machine
/* State Machine (TODO create Figma flow chart for this for reference)
* disconnected
*
*
*
*/
class SensorProvider extends ChangeNotifier {
// The list storing all the child instances
final List<SensorInstance> sensorInstances = [];
final List<SensorTypeModel> _sensorTypes = [];
// List of the physical sensors we've found from scanning
// Indexed by their the sensor type ID
final Map<String, List<String>> physicalSensors = {};
final Map<SensorTypeModel, dynamic> registeredScanSubscription = {};
// // Lists of the Sensor Model details -- no need for this i believe
// final List<SensorInstanceModel> _sensorInstances = [];
// Constructor (without subclass-instance creation)
SensorProvider();
List<SensorTypeModel> getAllSensorTypes() => _sensorTypes;
SensorTypeModel? getSensorType(String sensorTypeID) =>
_sensorTypes.where((s) => s.id == sensorTypeID).firstOrNull;
// TODO set third party respondent ID for current user
SensorInstance getSensorFromType(String sensorTypeID) =>
//_sensorTypes.firstWhere((s) => s.id == sensorTypeID);
sensorInstances.firstWhere((s) => s.getTypeModel().id == sensorTypeID);
SensorInstance? getSensorFromInstanceID(String sensorInstanceID) =>
sensorInstances
.where((s) => s.getSensorInstance().id == sensorInstanceID)
.firstOrNull;
SensorInstance? getSensorFromInstanceDeviceID(
String sensorInstanceDeviceID) =>
sensorInstances
.where(
(s) => s.getSensorInstance().deviceID == sensorInstanceDeviceID)
.firstOrNull;
List<SensorInstance> getAllSensorsOfType(String sensorTypeID) =>
sensorInstances
.where((s) => s.getTypeModel().id == sensorTypeID)
.toList();
// Gets you a sensor for a given type that is recording
SensorInstance? getCurrentlyRecordingSensorOfType(String sensorTypeID) =>
sensorInstances
.where((s) =>
s.getTypeModel().id == sensorTypeID &&
(s.sState == SensorState.connected_acquiring ||
s.sState == SensorState.disconnected_acquiring))
.firstOrNull;
List<MetricModel> getMetricsFromSensorTypeIDs(List<String> sensorIDs) {
final metrics = <MetricModel>[];
for (final sensorID in sensorIDs) {
final sensorInstance =
sensorInstances.firstWhere((s) => s.getTypeModel().id == sensorID);
final sensorType = sensorInstance.getTypeModel();
for (final metric in sensorType.canRecord) {
// Only add if we don't already have it
if (!metrics.any((m) => m.id == metric.id)) {
metrics.add(metric);
}
}
}
return metrics;
}
void updateEverything() {
notifyListeners();
}
void resetEverything() {
_sensorTypes.clear();
physicalSensors.clear();
for (final sub in registeredScanSubscription.values) {
sub?.cancel();
}
registeredScanSubscription.clear();
sensorInstances.clear();
notifyListeners();
}
// will get the sensor types from the backend
void setSensors(List<dynamic> sensors) {
for (final sensor in sensors) {
// TODO: do we even need to retrieve sensor instances on client side? -- I think so, for the sensors that connects to the edge-device (client?)
try {
final sensorType =
SensorTypeModel.fromMap(sensor['sensors_id']['model']);
final sensorDevice = SensorInstanceModel.fromMap(sensor['sensors_id']);
if (_sensorTypes.any((s) => s.id == sensorType.id)) {
// Find the study in the list and remove it
_sensorTypes.removeWhere((s) => s.id == sensorType.id);
}
_sensorTypes.add(sensorType);
final sensorInst =
SensorInstance.create(this, sensorDevice, sensorType);
// Register scan function to keep track of sensors we've physically encountered
if (!registeredScanSubscription.containsKey(sensorType)) {
registeredScanSubscription[sensorType] =
sensorInst.scanForSensor((deviceID) {
log('Device of type ${sensorType.id} found from scan: $deviceID');
if (physicalSensors[sensorType.id] == null ||
!physicalSensors[sensorType.id]!.contains(deviceID) &&
sensorInstances.any(
(s) => s.getSensorInstance().deviceID == deviceID)) {
physicalSensors[sensorType.id] = [
...?physicalSensors[sensorType.id],
deviceID
];
}
notifyListeners();
});
}
// Create sensor instance and add to list of sensor instances
sensorInstances.add(sensorInst);
} catch (e) {
log('Error parsing sensor: ${e.toString()}');
}
}
notifyListeners();
}
// // A method to add a child instance to the list
// static void addSensorInstanceToList(SensorInstance sensor) {
// sensorInstances.add(sensor);
// }
}
Editor is loading...
Leave a Comment