using System; using System.Collections.Generic; using System.Globalization; using Sensors; using Sensors.Polar; using UniRx; using UnityEngine; namespace Logging { public readonly struct PolarSensorEcgLog : ISerializable { private readonly long timestamp; private readonly float ecg; public PolarSensorEcgLog(int timestamp, float ecg) { this.timestamp = timestamp; this.ecg = ecg; } public KeyValuePair Serialize() => new KeyValuePair(timestamp, new[] { ecg.ToString("F4", CultureInfo.InvariantCulture) }); } public class PolarEcgDataLogger : SensorDataLogger { public override string Key => "polar_ecg_data"; private long startTime = -1; private TimeSync timeSync; private const int ECG_SAMPLE_RATE = 130; private IDisposable sub; public override async void Start() { base.Start(); timeSync = new TimeSync { StartTime = DateTime.Now, DifDataStreamStart = -1 }; var bikeSensorData = BikeSensorData.Instance; await bikeSensorData.PolarReceiverAvailable; sub = bikeSensorData.RawEcgData?.Subscribe(data => OnData(data)); } private void OnData(in EcgData data) { if (timeSync.DifDataStreamStart < 0) { timeSync.DifDataStreamStart = (long) (DateTime.Now - timeSync.StartTime).TotalMilliseconds; } if (startTime < 0) { startTime = data.Timestamp; } var internalTimestamp = (data.Timestamp - startTime) / 1000000; var timestamp = Mathf.RoundToInt(internalTimestamp + timeSync.DifDataStreamStart); foreach (var item in data.Values) { Log(new PolarSensorEcgLog(timestamp, item)); timestamp += 1000 / ECG_SAMPLE_RATE; } } public override IEnumerable ReadLog(IEnumerable> lines) { throw new System.NotImplementedException(); //TODO } private void OnDestroy() { sub?.Dispose(); } } }