using System; using System.Data; using System.Threading.Tasks; using ANT_Managed_Library; using JetBrains.Annotations; using Sensors.ANT; 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 PolarReceiver polarReceiver; [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 PolarSensorData? PolarData => polarReceiver?.SensorData; [CanBeNull] public IObservable RawEcgData => polarReceiver?.RawEcgData; [CanBeNull] public IObservable RawAccData => polarReceiver?.RawAccData; public PolarSensorConfig? PolarConfig => polarReceiver?.SensorConfig; public Task PolarReceiverAvailable { get; } public void StartListening(SpeedSensorConfig? speedSensorConfig = null, PolarSensorConfig? polarSensorConfig = null, int? powermeterId = null, int? hrAntId = null) { if (speedSensorConfig != null) { if (speedSensorReceiver != null) throw new InvalidConstraintException( "BikeSensorData: Already listening to Speed Sensor"); speedSensorReceiver = new SpeedSensorReceiver(speedSensorConfig.Value); try { speedSensorReceiver.StartScan(); } catch (ANT_Exception e) { Debug.Log($"Could not initialize SpeedSensorReceiver: {e}"); speedSensorReceiver = null; } } if (hrAntId != null) { if (hrReceiver != null) throw new InvalidConstraintException( "BikeSensorData: Already listening to HR Sensor"); hrReceiver = new HrReceiver(hrAntId.Value); try { hrReceiver.StartScan(); } catch (ANT_Exception e) { Debug.Log($"Could not initialize HR Receiver: {e}"); hrReceiver = null; } } if (powermeterId != null) { if (powerMeterReceiver != null) throw new InvalidConstraintException( "BikeSensorData: Already listening to Power Sensor"); powerMeterReceiver = new PowerMeterReceiver(powermeterId.Value); try { powerMeterReceiver.StartScan(); } catch (ANT_Exception e) { Debug.Log($"Could not initialize PowerMeter Receiver: {e}"); powerMeterReceiver = null; } } if (polarSensorConfig != null) { if (polarReceiver != null) throw new InvalidConstraintException( "BikeSensorData: Already listening to Polar Sensor"); polarReceiver = new PolarReceiver(polarSensorConfig.Value); polarReceiver.StartListening(); polarReceiverAvailable.OnNext(null); polarReceiverAvailable.OnCompleted(); } } public void Dispose() { polarReceiver?.Dispose(); //TODO: also dispose ANT sensors? polarReceiverAvailable.Dispose(); polarReceiver = 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 } }