internal static Type DetectHealthVaultTypeFromObservation(Observation observation)
        {
            if (observation.Code != null && observation.Code.Coding != null)
            {
                foreach (var code in observation.Code.Coding)
                {
                    if (!String.IsNullOrWhiteSpace(code.System) && code.CodeElement != null)
                    {
                        if (HealthVaultVocabularies.SystemContainsHealthVaultUrl(code.System))
                        {
                            var uri = new Uri(code.System.ToLowerInvariant());
                            return(DetectFromHealthVaultCode(uri.Segments.Last(), code.CodeElement.Value));
                        }

                        switch (code.System.ToLowerInvariant())
                        {
                        case VocabularyUris.SnomedCd:
                            return(DetectFromSnomedCd(code.CodeElement.Value));

                        case VocabularyUris.Loinc:
                            return(DetectFromLoincCodes(code.CodeElement.Value));
                        }
                    }
                }
            }

            throw new NotSupportedException();
        }
        internal static string GetVocabularyName(Uri uri)
        {
            if (HealthVaultVocabularies.SystemContainsHealthVaultUrl(uri.ToString()))
            {
                return(uri.Segments.Last());
            }

            return(null);
        }
        private static string GetSystemUrl(CodedValue codedValue)
        {
            // If the coded value family contains a URL, it's not a healvault vocab and we should return it as is
            if (codedValue.Family.Contains("http"))
            {
                return(codedValue.Family);
            }

            return(HealthVaultVocabularies.GenerateSystemUrl(codedValue.VocabularyName, codedValue.Family));
        }
        internal static FhirMedication ToFhirInternal(HVMedication hvMedication, FhirMedication fhirMedication)
        {
            fhirMedication.Code = hvMedication.Name.ToFhir();

            if (hvMedication.GenericName != null || hvMedication.Strength != null)
            {
                var medicationExtension = new Extension {
                    Url = HealthVaultExtensions.Medication
                };

                if (hvMedication.GenericName != null)
                {
                    var genericName = hvMedication.GenericName?.ToFhir();

                    medicationExtension.AddExtension(HealthVaultExtensions.MedicationGenericName,
                                                     genericName);
                }

                if (hvMedication.Strength != null)
                {
                    var strengthExtension = new Extension {
                        Url = HealthVaultExtensions.MedicationStrength
                    };

                    strengthExtension.AddExtension(HealthVaultExtensions.MedicationStrengthDisplay,
                                                   new FhirString(hvMedication.Strength.Display));

                    foreach (var structuredMeasurement in hvMedication.Strength.Structured)
                    {
                        var simpleQuantity = new SimpleQuantity()
                        {
                            Value = new decimal(structuredMeasurement.Value),
                            Unit  = structuredMeasurement.Units.Text
                        };

                        if (structuredMeasurement.Units.Any())
                        {
                            CodedValue measurementUnit = structuredMeasurement.Units.First();

                            simpleQuantity.Code   = measurementUnit.Value;
                            simpleQuantity.System = HealthVaultVocabularies.GenerateSystemUrl(measurementUnit.VocabularyName, measurementUnit.Family);
                        }

                        strengthExtension.AddExtension(HealthVaultExtensions.MedicationStrengthQuantity, simpleQuantity);
                    }

                    medicationExtension.Extension.Add(strengthExtension);
                }

                fhirMedication.Extension.Add(medicationExtension);
            }

            return(fhirMedication);
        }
Example #5
0
        private static string GetSystemUrl(CodedValue codedValue)
        {
            bool isNonHealthVaultVocabulary = codedValue.VocabularyName.Contains("http");

            if (isNonHealthVaultVocabulary)
            {
                return(codedValue.VocabularyName);
            }

            return(HealthVaultVocabularies.GenerateSystemUrl(codedValue.VocabularyName, codedValue.Family));
        }
Example #6
0
        public static CodedValue ToCodedValue(this Coding coding)
        {
            var familyVocab = HealthVaultVocabularies.ExtractFamilyAndVocabularyFromSystemUrl(coding.System);
            var returnValue = new CodedValue
            {
                Value          = coding.Code,
                VocabularyName = familyVocab.vocabulary,
                Family         = familyVocab.family,
                Version        = coding.Version,
            };

            return(returnValue);
        }
        internal static Observation ToFhirInternal(BodyComposition bodyComposition, Observation observation)
        {
            observation.Category = new List <CodeableConcept> {
                FhirCategories.VitalSigns
            };

            observation.Effective = bodyComposition.When.ToFhir();

            observation.Code = HealthVaultVocabularies.GenerateCodeableConcept(HealthVaultThingTypeNameCodes.BodyComposition);

            if (bodyComposition.MeasurementName != null)
            {
                observation.Component.Add(new Observation.ComponentComponent {
                    Code = bodyComposition.MeasurementName.ToFhir()
                });
            }

            if (bodyComposition.Value.MassValue != null)
            {
                var massValue = new Observation.ComponentComponent
                {
                    Code  = bodyComposition.MeasurementName.ToFhir(),
                    Value = new Quantity((decimal)bodyComposition.Value.MassValue.Kilograms, UnitAbbreviations.Kilogram)
                };
                observation.Component.Add(massValue);
            }

            if (bodyComposition.Value.PercentValue.HasValue)
            {
                var percentageValue = new Observation.ComponentComponent
                {
                    Code  = bodyComposition.MeasurementName.ToFhir(),
                    Value = new Quantity((decimal)bodyComposition.Value.PercentValue.Value, UnitAbbreviations.Percent)
                };
                observation.Component.Add(percentageValue);
            }

            if (bodyComposition.Site != null)
            {
                observation.BodySite = bodyComposition.Site.ToFhir();
            }

            if (bodyComposition.MeasurementMethod != null)
            {
                observation.Method = bodyComposition.MeasurementMethod.ToFhir();
            }

            return(observation);
        }
        internal static string GetFamily(Uri uri)
        {
            if (HealthVaultVocabularies.SystemContainsHealthVaultUrl(uri.ToString()))
            {
                // Expected to cotain 6 if the family is specified in the URL
                if (uri.Segments.Length == 6)
                {
                    return(uri.Segments[4].TrimEnd('/'));
                }

                // By default if nothing is specified, then wc is assumed
                return("wc");
            }

            return(null);
        }
Example #9
0
        internal static BloodGlucose ToBloodGlucose(this Observation observation)
        {
            var bloodGlucose = observation.ToThingBase <BloodGlucose>();

            bloodGlucose.Value = ObservationToHealthVault.GetThingValueFromQuantity <BloodGlucoseMeasurement>(observation.Value as Quantity);

            bloodGlucose.When = ObservationToHealthVault.GetWhenFromEffective(observation.Effective);

            var bloodGlucoseExtension = observation.GetExtension(HealthVaultExtensions.BloodGlucose);

            if (bloodGlucoseExtension != null)
            {
                bloodGlucose.MeasurementContext          = bloodGlucoseExtension.GetExtensionValue <CodeableConcept>(HealthVaultExtensions.BloodGlucoseMeasurementContext).ToCodableValue();
                bloodGlucose.OutsideOperatingTemperature = bloodGlucoseExtension.GetBoolExtension(HealthVaultExtensions.OutsideOperatingTemperatureExtensionName);
                bloodGlucose.IsControlTest = bloodGlucoseExtension.GetBoolExtension(HealthVaultExtensions.IsControlTestExtensionName);

                Normalcy normalcy;
                if (Enum.TryParse <Normalcy>(bloodGlucoseExtension.GetStringExtension(HealthVaultExtensions.ReadingNormalcyExtensionName), out normalcy))
                {
                    bloodGlucose.ReadingNormalcy = normalcy;
                }
            }

            if (observation.Code != null && observation.Code.Coding != null)
            {
                foreach (var code in observation.Code.Coding)
                {
                    if (HealthVaultVocabularies.SystemContainsHealthVaultUrl(code.System))
                    {
                        bloodGlucose.GlucoseMeasurementType = observation.Method.ToCodableValue();
                    }
                    else
                    {
                        bloodGlucose.SetGlucoseMeasurementType(
                            code.Display,
                            code.Code,
                            HealthVaultVocabularies.Fhir,
                            code.System,
                            code.Version);
                    }
                }
            }

            return(bloodGlucose);
        }
        internal static Observation ToFhirInternal(BodyDimension bodyDimension, Observation observation)
        {
            observation.Category = new List <CodeableConcept> {
                FhirCategories.VitalSigns
            };

            observation.Code = HealthVaultVocabularies.GenerateCodeableConcept(HealthVaultThingTypeNameCodes.BodyDimension);

            if (bodyDimension.MeasurementName != null)
            {
                observation.Method = bodyDimension.MeasurementName.ToFhir();
            }

            observation.Value = new Quantity((decimal)bodyDimension.Value.Meters, UnitAbbreviations.Meter);

            observation.Effective = bodyDimension.When.ToFhir();

            return(observation);
        }
Example #11
0
        private static Extension CreateDetailExtension(string key, ExerciseDetail exerciseDetail)
        {
            var extension = new Extension
            {
                Url = HealthVaultExtensions.ExerciseDetail
            };

            extension.AddExtension(HealthVaultExtensions.ExerciseDetailName, new FhirString(key));

            extension.AddExtension(HealthVaultExtensions.ExerciseDetailType, exerciseDetail.Name.ToFhir());

            extension.AddExtension(HealthVaultExtensions.ExerciseDetailValue, new Quantity
            {
                Value  = (decimal)exerciseDetail.Value.Value,
                Unit   = exerciseDetail.Value.Units.Text,
                Code   = exerciseDetail.Value.Units[0].Value,
                System = HealthVaultVocabularies.GenerateSystemUrl(exerciseDetail.Value.Units[0].VocabularyName, exerciseDetail.Value.Units[0].Family),
            });
            return(extension);
        }
        internal static Observation ToFhirInternal(BloodGlucose bg, Observation observation)
        {
            observation.Method = bg.GlucoseMeasurementType.ToFhir();

            var bloodGlucoseExtension = new Extension
            {
                Url = HealthVaultExtensions.BloodGlucose
            };

            if (bg.MeasurementContext != null)
            {
                bloodGlucoseExtension.AddExtension(HealthVaultExtensions.BloodGlucoseMeasurementContext, bg.MeasurementContext.ToFhir());
            }

            if (bg.OutsideOperatingTemperature.HasValue)
            {
                bloodGlucoseExtension.AddExtension(HealthVaultExtensions.OutsideOperatingTemperatureExtensionName, new FhirBoolean(bg.OutsideOperatingTemperature.Value));
            }

            if (bg.ReadingNormalcy.HasValue)
            {
                bloodGlucoseExtension.AddExtension(HealthVaultExtensions.ReadingNormalcyExtensionName, new FhirString(bg.ReadingNormalcy.Value.ToString()));
            }

            if (bg.IsControlTest.HasValue)
            {
                bloodGlucoseExtension.AddExtension(HealthVaultExtensions.IsControlTestExtensionName, new FhirBoolean(bg.IsControlTest.Value));
            }

            observation.Extension.Add(bloodGlucoseExtension);

            observation.Code = HealthVaultVocabularies.GenerateCodeableConcept(HealthVaultThingTypeNameCodes.BloodGlucose);

            var quantity = new Quantity((decimal)bg.Value.Value, UnitAbbreviations.MillimolesPerLiter);

            observation.Value     = quantity;
            observation.Effective = new FhirDateTime(bg.When.ToLocalDateTime().ToDateTimeUnspecified());

            return(observation);
        }
Example #13
0
        internal static Observation ToFhirInternal(BloodPressure bp, Observation observation)
        {
            if (bp.IrregularHeartbeatDetected.HasValue)
            {
                observation.AddExtension(HealthVaultVocabularies.IrregularHeartBeatExtensionName, new FhirBoolean(bp.IrregularHeartbeatDetected.Value));
            }

            var diastolicComponent = new Observation.ComponentComponent
            {
                Code  = HealthVaultVocabularies.GenerateCodeableConcept(HealthVaultVitalStatisticsCodes.BloodPressureDiastolic),
                Value = new Quantity((decimal)bp.Diastolic, UnitAbbreviations.MillimeterOfMecury)
            };

            var systolicComponent = new Observation.ComponentComponent
            {
                Code  = HealthVaultVocabularies.GenerateCodeableConcept(HealthVaultVitalStatisticsCodes.BloodPressureSystolic),
                Value = new Quantity((decimal)bp.Systolic, UnitAbbreviations.MillimeterOfMecury)
            };

            observation.Component = new List <Observation.ComponentComponent> {
                diastolicComponent, systolicComponent
            };

            if (bp.Pulse != null)
            {
                observation.Component.Add(new Observation.ComponentComponent
                {
                    Code  = HealthVaultVocabularies.GenerateCodeableConcept(HealthVaultVitalStatisticsCodes.HeartRate),
                    Value = new Quantity((decimal)bp.Pulse, UnitAbbreviations.PerMinute)
                });
            }

            observation.Effective = new FhirDateTime(bp.When.ToLocalDateTime().ToDateTimeUnspecified());
            observation.Code      = HealthVaultVocabularies.BloodPressure;

            return(observation);
        }
Example #14
0
        public static SimpleQuantity GetSimpleQuantity(GeneralMeasurement measurement)
        {
            if (measurement?.Structured.Any() == true)
            {
                StructuredMeasurement structuredMeasurement = measurement.Structured.First();

                var simpleQuantity = new SimpleQuantity()
                {
                    Value = new decimal(structuredMeasurement.Value),
                    Unit  = structuredMeasurement.Units.Text
                };

                if (structuredMeasurement.Units.Any())
                {
                    CodedValue measurementUnit = structuredMeasurement.Units.First();

                    simpleQuantity.Code   = measurementUnit.Value;
                    simpleQuantity.System = HealthVaultVocabularies.GenerateSystemUrl(measurementUnit.VocabularyName, measurementUnit.Family);
                }

                return(simpleQuantity);
            }
            return(null);
        }
Example #15
0
        internal static BloodPressure ToBloodPressure(this Observation observation)
        {
            var bloodPressure = observation.ToThingBase <BloodPressure>();

            bloodPressure.When = ObservationToHealthVault.GetHealthVaultTimeFromEffectiveDate(observation.Effective);

            bloodPressure.IrregularHeartbeatDetected = observation.GetBoolExtension(HealthVaultVocabularies.IrregularHeartBeatExtensionName);

            if (observation.Component != null)
            {
                foreach (var component in observation.Component)
                {
                    if (component.Code != null && component.Code.Coding != null)
                    {
                        foreach (var code in component.Code.Coding)
                        {
                            if (code.Code != null)
                            {
                                if (HealthVaultVocabularies.SystemContainsHealthVaultUrl(code.System))
                                {
                                    if (code.Code == HealthVaultVitalStatisticsCodes.BloodPressureDiastolic.Code)
                                    {
                                        SetDiastolic(bloodPressure, component);
                                    }
                                    else if (code.Code == HealthVaultVitalStatisticsCodes.BloodPressureSystolic.Code)
                                    {
                                        SetSystolic(bloodPressure, component);
                                    }
                                    else if (code.Code == HealthVaultVitalStatisticsCodes.HeartRate.Code)
                                    {
                                        SetPulse(bloodPressure, component);
                                    }
                                }
                                else
                                {
                                    switch (code.Code.ToLowerInvariant())
                                    {
                                    // HeartRate component
                                    case "8867-4":
                                        SetPulse(bloodPressure, component);
                                        break;

                                    // Systolic LOINC, SNOMED, ACME codes
                                    case "8480-6":
                                    case "271649006":
                                    case "bp-s":
                                        SetSystolic(bloodPressure, component);
                                        break;

                                    // Diastolic LOINC code
                                    case "8462-4":
                                        SetDiastolic(bloodPressure, component);
                                        break;

                                    default:
                                        continue;
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            return(bloodPressure);
        }
        public static Allergy ToHealthVault(this AllergyIntolerance allergyIntolerance)
        {
            if (allergyIntolerance.Code.IsNullOrEmpty())
            {
                throw new System.ArgumentException($"Can not transform a {typeof(AllergyIntolerance)} with no code into {typeof(Allergy)}");
            }

            var allergy = allergyIntolerance.ToThingBase <Allergy>();

            string allergenType     = string.Empty;
            var    allergyExtension = allergyIntolerance.GetExtension(HealthVaultExtensions.Allergy);

            if (allergyExtension != null)
            {
                allergenType         = allergyExtension.GetStringExtension(HealthVaultExtensions.AllergenType);
                allergy.AllergenCode = allergyExtension.GetExtensionValue <CodeableConcept>(HealthVaultExtensions.AllergenCode)?.ToCodableValue();
                allergy.Treatment    = allergyExtension.GetExtensionValue <CodeableConcept>(HealthVaultExtensions.AllergyTreatement)?.ToCodableValue();
            }

            var coding = allergyIntolerance.Code.Coding.FirstOrDefault();

            if (coding != null)
            {
                if (HealthVaultVocabularies.SystemContainsHealthVaultUrl(coding.System))
                {
                    allergy.Name = allergyIntolerance.Code.ToCodableValue();
                }
                else
                {
                    allergy.SetAllergyName(
                        coding.Display,
                        coding.Code,
                        HealthVaultVocabularies.Fhir,
                        coding.System,
                        coding.Version);
                }
            }

            if (allergyIntolerance.Reaction != null && allergyIntolerance.Reaction.Count > 0)
            {
                var code = allergyIntolerance.Reaction.First().Manifestation.First().Coding.FirstOrDefault();
                if (code != null)
                {
                    if (HealthVaultVocabularies.SystemContainsHealthVaultUrl(code.System))
                    {
                        allergy.Reaction = allergyIntolerance.Reaction.First().Manifestation.First().ToCodableValue();
                    }
                    else
                    {
                        allergy.SetAllergyReaction(
                            code.Display,
                            code.Code,
                            HealthVaultVocabularies.Fhir,
                            code.System,
                            code.Version);
                    }
                }
            }

            if (allergyIntolerance.Onset != null)
            {
                allergy.FirstObserved = allergyIntolerance.Onset.ToAproximateDateTime();
            }

            if (!string.IsNullOrWhiteSpace(allergenType))
            {
                allergy.AllergenType = new CodableValue(allergenType)
                {
                    new CodedValue(allergenType, HealthVaultVocabularies.AllergenType, HealthVaultVocabularies.Wc, "1")
                };
            }
            else if (allergyIntolerance.Category != null && allergyIntolerance.Category.Count() > 0)
            {
                allergy.AllergenType = new CodableValue(allergyIntolerance.Category.First().Value.ToString())
                {
                    new CodedValue(allergyIntolerance.Category.First().Value.ToString(), FhirCategories.HL7Allergy, HealthVaultVocabularies.Fhir, "")
                };
            }

            if (allergyIntolerance.ClinicalStatus.HasValue)
            {
                if ((allergyIntolerance.ClinicalStatus.Value == (AllergyIntoleranceClinicalStatus.Resolved)) || (allergyIntolerance.ClinicalStatus.Value == (AllergyIntoleranceClinicalStatus.Inactive)))
                {
                    allergy.IsNegated = true;
                }
                else
                {
                    allergy.IsNegated = false;
                }
            }

            if (allergyIntolerance.Asserter != null)
            {
                allergy.TreatmentProvider = GetProvider(allergyIntolerance);
            }

            return(allergy);
        }
        public void WhenMedicationStatementTransformedToHealthVault_ThenDosageIsCopiedToDoseFrequencyAndRoute()
        {
            var embeddedMedication = new FhirMedication()
            {
                Code = new CodeableConcept()
                {
                    Text = "Amoxicillin 250mg/5ml Suspension"
                }
            };
            string embeddedMedicationId = "med" + Guid.NewGuid();

            embeddedMedication.Id = embeddedMedicationId;

            const int    dosage              = 1;
            const int    period              = 8;
            const string routeCode           = "po";
            var          medicationStatement = new MedicationStatement()
            {
                Medication = new ResourceReference(embeddedMedicationId),
                Dosage     = new System.Collections.Generic.List <Dosage>
                {
                    new Dosage
                    {
                        Dose = new SimpleQuantity()
                        {
                            Value  = dosage,
                            Unit   = "Tablets",
                            System = HealthVaultVocabularies.GenerateSystemUrl
                                         (HealthVaultVocabularies.MedicationDoseUnits,
                                         HealthVaultVocabularies.Wc),
                            Code = "tablet"
                        },
                        Timing = new Timing
                        {
                            Repeat = new Timing.RepeatComponent
                            {
                                Period     = period,
                                PeriodUnit = Timing.UnitsOfTime.H
                            }
                        },
                        Route = new CodeableConcept
                        {
                            Text   = "By mouth",
                            Coding = new System.Collections.Generic.List <Coding>
                            {
                                new Coding
                                {
                                    Code   = routeCode,
                                    System = HealthVaultVocabularies.GenerateSystemUrl
                                                 (HealthVaultVocabularies.MedicationRoutes,
                                                 HealthVaultVocabularies.Wc),
                                    Version = "2"
                                }
                            }
                        }
                    }
                }
            };

            medicationStatement.Contained.Add(embeddedMedication);
            medicationStatement.Medication = embeddedMedication.GetContainerReference();

            var hvMedication = medicationStatement.ToHealthVault() as HVMedication;

            Assert.AreEqual(dosage, hvMedication?.Dose?.Structured?.First()?.Value);
            Assert.AreEqual(period, hvMedication?.Frequency?.Structured?.First()?.Value);
            Assert.AreEqual(routeCode, hvMedication?.Route?.First()?.Value);
        }
Example #18
0
        internal static Observation ToFhirInternal(Exercise exercise, Observation observation)
        {
            observation.Code = HealthVaultVocabularies.GenerateCodeableConcept(HealthVaultThingTypeNameCodes.Exercise);

            if (exercise.Distance != null)
            {
                var distanceValue = new Observation.ComponentComponent
                {
                    Code = new CodeableConcept {
                        Text = HealthVaultVocabularies.ExerciseDistance
                    },
                    Value = new Quantity((decimal)exercise.Distance.Value, UnitAbbreviations.Meter)
                };
                observation.Component.Add(distanceValue);
            }

            if (exercise.Duration != null)
            {
                var durationValue = new Observation.ComponentComponent
                {
                    Code = new CodeableConcept {
                        Text = HealthVaultVocabularies.ExerciseDuration
                    },
                    Value = new Quantity((decimal)exercise.Duration.Value, UnitAbbreviations.Minute)
                };
                observation.Component.Add(durationValue);
            }

            observation.Text = new Narrative
            {
                Div = exercise.Title
            };

            observation.Effective = exercise.When.ToFhir();

            var activityValue = new Observation.ComponentComponent
            {
                Code = new CodeableConcept {
                    Text = HealthVaultVocabularies.ExerciseActivity
                },
                Value = exercise.Activity.ToFhir()
            };

            observation.Component.Add(activityValue);

            if (exercise.Details != null)
            {
                foreach (var detail in exercise.Details)
                {
                    observation.Extension.Add(CreateDetailExtension(detail.Key, detail.Value));
                }
            }

            if (!exercise.Segments.IsNullOrEmpty())
            {
                foreach (var segment in exercise.Segments)
                {
                    observation.Extension.Add(CreateSegmentExtension(segment));
                }
            }

            return(observation);
        }
Example #19
0
        internal static Observation ToFhirInternal(SleepJournalAM sleepJournalAM, Observation observation)
        {
            observation.Code = HealthVaultVocabularies.GenerateCodeableConcept(HealthVaultThingTypeNameCodes.SleepJournalAM);

            observation.Effective = new FhirDateTime(sleepJournalAM.When.ToLocalDateTime().ToDateTimeUnspecified());

            observation.Component = new List <Observation.ComponentComponent>();

            var bedtimeComponent = new Observation.ComponentComponent
            {
                Code = new CodeableConcept {
                    Text = HealthVaultVocabularies.SleepJournalAMBedtime
                },
                Value = sleepJournalAM.Bedtime.ToFhir()
            };

            observation.Component.Add(bedtimeComponent);

            var waketimeComponent = new Observation.ComponentComponent
            {
                Code = new CodeableConcept {
                    Text = HealthVaultVocabularies.SleepJournalAMWaketime
                },
                Value = sleepJournalAM.WakeTime.ToFhir()
            };

            observation.Component.Add(waketimeComponent);

            var sleepMinutesComponent = new Observation.ComponentComponent
            {
                Code = new CodeableConcept {
                    Text = HealthVaultVocabularies.SleepJournalAMSleepMinutes
                },
                Value = new Quantity(sleepJournalAM.SleepMinutes, UnitAbbreviations.Minute)
            };

            observation.Component.Add(sleepMinutesComponent);

            var settlingMinutesComponent = new Observation.ComponentComponent
            {
                Code = new CodeableConcept {
                    Text = HealthVaultVocabularies.SleepJournalAMSettlingMinutes
                },
                Value = new Quantity(sleepJournalAM.SettlingMinutes, UnitAbbreviations.Minute)
            };

            observation.Component.Add(settlingMinutesComponent);

            if (sleepJournalAM.Awakenings != null)
            {
                foreach (var awakening in sleepJournalAM.Awakenings)
                {
                    var dummyDateTimeStart = new DateTime(sleepJournalAM.When.Date.Year, sleepJournalAM.When.Date.Month, sleepJournalAM.When.Date.Day);
                    dummyDateTimeStart = dummyDateTimeStart.AddHours(awakening.When.Hour);
                    dummyDateTimeStart = dummyDateTimeStart.AddMinutes(awakening.When.Minute);
                    if (awakening.When.Second.HasValue)
                    {
                        dummyDateTimeStart = dummyDateTimeStart.AddSeconds(awakening.When.Second.Value);
                    }

                    if (awakening.When.Millisecond.HasValue)
                    {
                        dummyDateTimeStart = dummyDateTimeStart.AddSeconds(awakening.When.Millisecond.Value);
                    }

                    var dummyDateTimeEnd = dummyDateTimeStart;
                    dummyDateTimeEnd = dummyDateTimeEnd.AddMinutes(awakening.Minutes);

                    var awakeningComponent = new Observation.ComponentComponent
                    {
                        Code = new CodeableConcept {
                            Text = HealthVaultVocabularies.SleepJournalAMAwakening
                        },
                        Value = new Period(new FhirDateTime(dummyDateTimeStart), new FhirDateTime(dummyDateTimeEnd)),
                    };
                    observation.Component.Add(awakeningComponent);
                }
            }

            var wakeStateComponent = new Observation.ComponentComponent
            {
                Code = new CodeableConcept {
                    Text = HealthVaultVocabularies.SleepJournalAMWakeState
                },
                Value = new FhirString(sleepJournalAM.WakeState.ToString()),
            };

            observation.Component.Add(wakeStateComponent);

            if (sleepJournalAM.Medications != null)
            {
                var medicationComponenet = new Observation.ComponentComponent
                {
                    Code = new CodeableConcept {
                        Text = HealthVaultVocabularies.SleepJournalAMMedication
                    },
                    Value = sleepJournalAM.Medications.ToFhir(),
                };
                observation.Component.Add(medicationComponenet);
            }

            return(observation);
        }
        internal static CodableValue CreateCodableValueFromQuantityValues(string system, string code, string unit)
        {
            var familyVocab = HealthVaultVocabularies.ExtractFamilyAndVocabularyFromSystemUrl(system);

            return(new CodableValue(unit, code, familyVocab.vocabulary, familyVocab.family, null));
        }