using System; using System.Collections.Generic; using System.Data; using System.Threading.Tasks; using ANT_Managed_Library; using JetBrains.Annotations; using Sensors.ANT; using Sensors.Bluetooth; using Sensors.Polar; using UniRx; using UnityEngine; namespace Sensors { public sealed class BikeSensorData { private readonly Subject polarReceiverAvailable = new Subject(); [CanBeNull] private HrReceiver hrReceiver; [CanBeNull] private BleReceiver bleReceiver; [CanBeNull] private PowerMeterReceiver powerMeterReceiver; [CanBeNull] private SpeedSensorReceiver speedSensorReceiver; private BikeSensorData() { PolarReceiverAvailable = polarReceiverAvailable.ToTask(); } public SpeedSensorData? SpeedData => speedSensorReceiver?.Connected ?? false ? speedSensorReceiver?.SensorData : null; public PowermeterSensorData? PowermeterData => powerMeterReceiver?.Connected ?? false ? powerMeterReceiver?.SensorData : null; public HrSensorData? HrData => hrReceiver?.Connected ?? false ? hrReceiver?.SensorData : null; public BleSensorData? BleData => bleReceiver?.SensorData; [CanBeNull] public IObservable RawEcgData => bleReceiver?.RawEcgData; [CanBeNull] public IObservable RawAccData => bleReceiver?.RawAccData; public BleSensorConfig? PolarConfig => bleReceiver?.SensorConfig; public Task PolarReceiverAvailable { get; } public void StartListening(SpeedSensorConfig? speedSensorConfig = null, BleSensorConfig? polarSensorConfig = null, int? powermeterId = null, int? hrAntId = null) { var awaitDevices = new List(); if (speedSensorConfig != null) { if (speedSensorReceiver != null) throw new InvalidConstraintException( "BikeSensorData: Already listening to Speed Sensor"); speedSensorReceiver = new SpeedSensorReceiver(speedSensorConfig.Value); awaitDevices.Add(speedSensorReceiver); } if (hrAntId != null) { if (hrReceiver != null) throw new InvalidConstraintException( "BikeSensorData: Already listening to HR Sensor"); hrReceiver = new HrReceiver(hrAntId.Value); awaitDevices.Add(hrReceiver); } if (powermeterId != null) { if (powerMeterReceiver != null) throw new InvalidConstraintException( "BikeSensorData: Already listening to Power Sensor"); powerMeterReceiver = new PowerMeterReceiver(powermeterId.Value); //awaitDevices.Add(powerMeterReceiver); } if (awaitDevices.Count > 0) { try { AntDevices.Instance.StartScan(awaitDevices); } catch (Exception e) { Debug.Log($"Could not initialize Ant Devices: {e}"); hrReceiver = null; powerMeterReceiver = null; speedSensorReceiver = null; } } if (polarSensorConfig != null) { if (bleReceiver != null) throw new InvalidConstraintException( "BikeSensorData: Already listening to Polar Sensor"); bleReceiver = new BleReceiver(polarSensorConfig.Value); bleReceiver.StartListening(); polarReceiverAvailable.OnNext(null); polarReceiverAvailable.OnCompleted(); } } public void Dispose() { bleReceiver?.Dispose(); //TODO: also dispose ANT sensors? polarReceiverAvailable.Dispose(); bleReceiver = null; speedSensorReceiver = null; powerMeterReceiver = null; hrReceiver = null; } #region singleton private static readonly Lazy lazy = new Lazy (() => new BikeSensorData()); public static BikeSensorData Instance => lazy.Value; #endregion } }