BikeSensorData.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.Threading.Tasks;
  5. using ANT_Managed_Library;
  6. using JetBrains.Annotations;
  7. using Sensors.ANT;
  8. using Sensors.Bluetooth;
  9. using Sensors.Polar;
  10. using UniRx;
  11. using UnityEngine;
  12. namespace Sensors
  13. {
  14. public sealed class BikeSensorData
  15. {
  16. private readonly Subject<object> polarReceiverAvailable = new Subject<object>();
  17. [CanBeNull] private HrReceiver hrReceiver;
  18. [CanBeNull] private BleReceiver bleReceiver;
  19. [CanBeNull] private PowerMeterReceiver powerMeterReceiver;
  20. [CanBeNull] private SpeedSensorReceiver speedSensorReceiver;
  21. private BikeSensorData()
  22. {
  23. PolarReceiverAvailable = polarReceiverAvailable.ToTask();
  24. }
  25. public SpeedSensorData? SpeedData =>
  26. speedSensorReceiver?.Connected ?? false ? speedSensorReceiver?.SensorData : null;
  27. public PowermeterSensorData? PowermeterData =>
  28. powerMeterReceiver?.Connected ?? false ? powerMeterReceiver?.SensorData : null;
  29. public HrSensorData? HrData => hrReceiver?.Connected ?? false ? hrReceiver?.SensorData : null;
  30. public BleSensorData? BleData => bleReceiver?.SensorData;
  31. [CanBeNull] public IObservable<EcgData> RawEcgData => bleReceiver?.RawEcgData;
  32. [CanBeNull] public IObservable<AccData> RawAccData => bleReceiver?.RawAccData;
  33. public BleSensorConfig? PolarConfig => bleReceiver?.SensorConfig;
  34. public Task PolarReceiverAvailable { get; }
  35. public void StartListening(SpeedSensorConfig? speedSensorConfig = null,
  36. BleSensorConfig? polarSensorConfig = null, int? powermeterId = null, int? hrAntId = null)
  37. {
  38. var awaitDevices = new List<AwaitDevice>();
  39. if (speedSensorConfig != null)
  40. {
  41. if (speedSensorReceiver != null)
  42. throw new InvalidConstraintException(
  43. "BikeSensorData: Already listening to Speed Sensor");
  44. speedSensorReceiver = new SpeedSensorReceiver(speedSensorConfig.Value);
  45. awaitDevices.Add(speedSensorReceiver);
  46. }
  47. if (hrAntId != null)
  48. {
  49. if (hrReceiver != null)
  50. throw new InvalidConstraintException(
  51. "BikeSensorData: Already listening to HR Sensor");
  52. hrReceiver = new HrReceiver(hrAntId.Value);
  53. awaitDevices.Add(hrReceiver);
  54. }
  55. if (powermeterId != null)
  56. {
  57. if (powerMeterReceiver != null)
  58. throw new InvalidConstraintException(
  59. "BikeSensorData: Already listening to Power Sensor");
  60. powerMeterReceiver = new PowerMeterReceiver(powermeterId.Value);
  61. awaitDevices.Add(powerMeterReceiver);
  62. }
  63. if (awaitDevices.Count > 0)
  64. {
  65. try
  66. {
  67. AntDevices.Instance.StartScan(awaitDevices);
  68. }
  69. catch (Exception e)
  70. {
  71. Debug.Log($"Could not initialize Ant Devices: {e}");
  72. hrReceiver = null;
  73. powerMeterReceiver = null;
  74. speedSensorReceiver = null;
  75. }
  76. }
  77. if (polarSensorConfig != null)
  78. {
  79. if (bleReceiver != null)
  80. throw new InvalidConstraintException(
  81. "BikeSensorData: Already listening to Polar Sensor");
  82. bleReceiver = new BleReceiver(polarSensorConfig.Value);
  83. bleReceiver.StartListening();
  84. polarReceiverAvailable.OnNext(null);
  85. polarReceiverAvailable.OnCompleted();
  86. }
  87. }
  88. public void Dispose()
  89. {
  90. bleReceiver?.Dispose();
  91. //TODO: also dispose ANT sensors?
  92. polarReceiverAvailable.Dispose();
  93. bleReceiver = null;
  94. speedSensorReceiver = null;
  95. powerMeterReceiver = null;
  96. hrReceiver = null;
  97. }
  98. #region singleton
  99. private static readonly Lazy<BikeSensorData>
  100. lazy =
  101. new Lazy<BikeSensorData>
  102. (() => new BikeSensorData());
  103. public static BikeSensorData Instance => lazy.Value;
  104. #endregion
  105. }
  106. }