BikeSensorData.cs 4.4 KB

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