private void SaveToDatabase() { try { if (_hrQueue.Count > 0) { _isConnectedToBluetoothDevice = true; var measurements = new List <HeartRateMeasurement>(); HeartRateMeasurement measurement = null; while (!_hrQueue.IsEmpty) { _hrQueue.TryDequeue(out measurement); if (measurement != null) { if (!double.IsNaN(_previousRR)) { measurement.RRDifference = Math.Abs(measurement.RRInterval - _previousRR); } _previousRR = measurement.RRInterval; measurements.Add(measurement); } } if (Settings.IsDetailedCollectionEnabled) { DatabaseConnector.AddHeartMeasurementsToDatabase(measurements, false); } var ts = (measurements.Count >= 0) ? measurements[0].Timestamp : string.Empty; var heartRateValues = measurements.Where(x => !double.IsNaN(x.HeartRateValue)).Select(x => x.HeartRateValue); var rrdifferences = measurements.Where(x => !double.IsNaN(x.RRDifference)).Select(x => x.RRDifference); var rrintervals = measurements.Where(x => !double.IsNaN(x.RRInterval)).Select(x => x.RRInterval); var averages = new HeartRateMeasurement() { HeartRateValue = (heartRateValues.Count() == 0) ? double.NaN : heartRateValues.Average(), RRDifference = (rrdifferences.Count() == 0) ? double.NaN : rrdifferences.Average(), RRInterval = (rrintervals.Count() == 0) ? double.NaN : rrintervals.Average(), Timestamp = ts }; DatabaseConnector.AddHeartMeasurementsToDatabase(new List <HeartRateMeasurement>() { averages }, true); } else { _isConnectedToBluetoothDevice = false; Logger.WriteToConsole("Nothing to save..."); } } catch (Exception e) { Logger.WriteToLogFile(e); } }
public static HeartRateMeasurement GetHeartRate(byte[] data) { // Heart Rate profile defined flag values const byte HEART_RATE_VALUE_FORMAT = 0x01; const byte ENERGY_EXPANDED_STATUS = 0x08; const byte RR = 0x10; // get flags byte currentOffset = 0; byte flags = data[currentOffset]; currentOffset++; var measurment = new HeartRateMeasurement(); // get heart rate value if ((flags & HEART_RATE_VALUE_FORMAT) != 0) { measurment.HeartRateValue = BitConverter.ToUInt16(data, currentOffset);// (ushort)((data[currentOffset + 1] << 8) + data[currentOffset]); currentOffset += 2; } else { measurment.HeartRateValue = data[currentOffset]; currentOffset++; } // get expended energy if ((flags & ENERGY_EXPANDED_STATUS) != 0) { measurment.HasExpendedEnergy = true; measurment.ExpendedEnergy = (ushort)((data[currentOffset + 1] << 8) + data[currentOffset]); currentOffset += 2; } else { measurment.HasExpendedEnergy = false; } if ((flags & RR) != 0) { // R-R information int rrCount = (data.Length - currentOffset) / 2; measurment.RRValues = new int[rrCount]; for (int i = 0; i < rrCount; i++) { measurment.RRValues[i] = BitConverter.ToUInt16(data, currentOffset); currentOffset += 2; } } // The Heart Rate Bluetooth profile can also contain sensor contact status information, // and R-Wave interval measurements, which can also be processed here. // For the purpose of this sample, we don't need to interpret that data. return(measurment); }