public HttpResponseMessage Create(Hl7.Fhir.Model.Observation fhirObservation)
        {
            HttpResponseMessage message = new HttpResponseMessage();

            Observation observation = ObservationMapper.MapResource(fhirObservation);

            observation = (Observation)ControllerUtils.AddMetadata(observation, ControllerUtils.CREATE);

            db.Observations.Add(observation);
            db.SaveChanges();

            message.Content          = new StringContent("Observation created!", Encoding.UTF8, "text/html");
            message.StatusCode       = HttpStatusCode.Created;
            message.Headers.Location = new Uri(Url.Link("SpecificObservation", new { id = observation.ObservationId }));

            return(message);
        }
        public HttpResponseMessage Read(int observationId, string _format = "application/xml+FHIR", bool _summary = false)
        {
            HttpResponseMessage message = new HttpResponseMessage();

            Observation observation = db.Observations.Find(observationId);

            if (observation == null)
            {
                message.StatusCode = HttpStatusCode.NotFound;
                message.Content    = new StringContent("observation with id " + observationId + " not found!", Encoding.UTF8, "text/html");
                return(message);
            }

            Hl7.Fhir.Model.Observation fhirObservation = ObservationMapper.MapModel(observation);
            string fixedFormat = ControllerUtils.FixMimeString(_format);

            string payload = ControllerUtils.Serialize(fhirObservation, fixedFormat, _summary);

            message.Content = new StringContent(payload, Encoding.UTF8, fixedFormat);
            return(message);
        }
        public HttpResponseMessage Update(Hl7.Fhir.Model.Observation fhirObservation, int observationId)
        {
            HttpResponseMessage message = new HttpResponseMessage();

            if (observationId != int.Parse(fhirObservation.Id))
            {
                message.StatusCode = HttpStatusCode.BadRequest;
                message.Content    = new StringContent("Mismatch of observation ID! Provided " + observationId + " in URL but found " + fhirObservation.Id + "in payload!", Encoding.UTF8, "text/html");
                return(message);
            }

            Observation observation = ObservationMapper.MapResource(fhirObservation);

            observation = (Observation)ControllerUtils.AddMetadata(observation, ControllerUtils.UPDATE);

            db.Entry(observation).State = EntityState.Modified;

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!ObservationExists(observationId))
                {
                    message.StatusCode = HttpStatusCode.NotFound;
                    message.Content    = new StringContent("observation with id " + observationId + " not found!", Encoding.UTF8, "text/html");
                    return(message);
                }
                else
                {
                    throw;
                }
            }

            message.StatusCode = HttpStatusCode.OK;
            return(message);
        }
示例#4
0
        private async Task MessageReceivedAsync(IDialogContext context, IAwaitable <object> result)
        {
            var    activity = await result as Activity;
            string msg      = activity.Text.ToLower().Trim();

            if (msg == "start over" || msg == "exit" || msg == "quit" || msg == "done" || msg == "start again" || msg == "restart" || msg == "leave" || msg == "reset" || msg == "bye" || msg == "goodbye")
            {
                context.Done("end");
            }
            else
            {
                if (isSessionTimedOut(context))
                {
                    context.Fail(new SessionTimedOutException("Your session has timedout or is invalid."));
                }
                else
                {
                    string fhirserver = null;
                    context.PrivateConversationData.TryGetValue <string>("fhirserver", out fhirserver);
                    string token = null;
                    context.PrivateConversationData.TryGetValue <string>("bearertoken", out token);
                    string patid = null;
                    context.PrivateConversationData.TryGetValue <string>("id", out patid);
                    //Initialize FHIR Client
                    FHIRClient client = new FHIRClient(fhirserver, token);
                    //Determine Intent/Entities from LUIS
                    var luisresp = await LUISClient.RequestAsync <LUISResponse>(activity.Text);

                    var intent = luisresp.topScoringIntent;

                    //Nothing over 50% confidence bail
                    if (intent == null)
                    {
                        await context.PostAsync($"Sorry, I didn't understand {activity.Text}...");
                    }

                    if (intent.intent == "FindPractitioner")
                    {
                        if (luisresp.entities == null || luisresp.entities.Count() == 0)
                        {
                            await context.PostAsync($"Sorry, I think you want to find a practioner but I can't determine the location you want");
                        }
                        //Handle Geography
                        var geo = luisresp.entities.FirstOrDefault();
                        //Call FHIR Server
                        string parm   = geo.entity.ToLower().StartsWith("anywhere") ? "" : $"city={geo.entity}";
                        var    bundle = (Hl7.Fhir.Model.Bundle)client.LoadResource("Practitioner", parm);
                        if (bundle.Entry.Count == 0)
                        {
                            await context.PostAsync($"Sorry, I couldn't find providers in {geo.entity}...");
                        }
                        else
                        {
                            StringBuilder sb = new StringBuilder();
                            sb.Append($"Got {bundle.Entry.Count()} practioners in {geo.entity}\n\n");
                            foreach (var entry in bundle.Entry)
                            {
                                Hl7.Fhir.Model.Practitioner p = (Hl7.Fhir.Model.Practitioner)entry.Resource;
                                var address = (p.Address.Count > 0 ? p.Address[0] : null);
                                var tel     = (p.Telecom.Count > 0 ? p.Telecom[0] : null);
                                sb.Append($"{p.Name[0].Text} is accepting new patients.");
                                if (address != null)
                                {
                                    sb.Append($"Located at " + address.LineElement[0] + " " + address.City);
                                }
                                if (tel != null)
                                {
                                    sb.Append($" Phone:" + tel.Value);
                                }
                                sb.Append("\n\n");
                            }
                            await context.PostAsync(sb.ToString());
                        }
                    }
                    else if (intent.intent == "ChartHeartRate")
                    {
                        var entity = luisresp.FindEntityByType("builtin.number");
                        if (entity != null)
                        {
                            var hr = Convert.ToDecimal(new String(entity.entity.Where(Char.IsDigit).ToArray()));
                            Hl7.Fhir.Model.Observation rv = new Hl7.Fhir.Model.Observation();
                            rv.Status   = Hl7.Fhir.Model.ObservationStatus.Final;
                            rv.Category = new List <Hl7.Fhir.Model.CodeableConcept>();
                            Hl7.Fhir.Model.CodeableConcept cc = new Hl7.Fhir.Model.CodeableConcept("http://hl7.org/fhir/observation-category", "vital-signs", "Vital Signs");
                            rv.Category.Add(cc);
                            rv.Code      = new Hl7.Fhir.Model.CodeableConcept("http://loinc.org", "8867-4", "Heart rate");
                            rv.Subject   = new Hl7.Fhir.Model.ResourceReference("patient/" + patid);
                            rv.Effective = Hl7.Fhir.Model.FhirDateTime.Now();
                            rv.Value     = new Hl7.Fhir.Model.Quantity(hr, "beats/minute");
                            var rslt = client.SaveResource(rv);
                            if (rslt)
                            {
                                await context.PostAsync($"Thanks, I recorded your heart rate of {entity.entity} in your medical record");
                            }
                            else
                            {
                                await context.PostAsync($"Sorry I had a problem posting your heartrate...try again later.");
                            }
                        }
                        else
                        {
                            await context.PostAsync($"Sorry, I think you want to record your heartrate vital but I can't understand the value you provided.");
                        }
                    }
                    else if (intent.intent == "ChartWeight")
                    {
                        string entity_weight = null;
                        var    entity        = luisresp.FindEntityByType("weight");
                        if (entity == null)
                        {
                            entity = luisresp.FindEntityByType("builtin.number");
                            if (entity != null)
                            {
                                entity_weight = entity.entity;
                                var wt = luisresp.FindEntityByType("builtin.dimension");
                                if (wt != null)
                                {
                                    if (wt.entity.ToLower().EndsWith("kilograms") || wt.entity.ToLower().EndsWith("kg"))
                                    {
                                        entity_weight = entity_weight + "kg";
                                    }
                                    else
                                    {
                                        entity_weight = entity_weight + "lbs";
                                    }
                                }
                            }
                        }
                        else
                        {
                            entity_weight = entity.entity;
                        }
                        if (entity_weight != null)
                        {
                            var weight = Convert.ToDecimal(new String(entity_weight.Where(Char.IsDigit).ToArray()));
                            //Determine pounds or kg
                            if (entity_weight.ToLower().EndsWith("kg"))
                            {
                                weight = weight * (decimal)2.20462;
                            }
                            Hl7.Fhir.Model.Observation rv = new Hl7.Fhir.Model.Observation();
                            rv.Status   = Hl7.Fhir.Model.ObservationStatus.Final;
                            rv.Category = new List <Hl7.Fhir.Model.CodeableConcept>();
                            Hl7.Fhir.Model.CodeableConcept cc = new Hl7.Fhir.Model.CodeableConcept("http://hl7.org/fhir/observation-category", "vital-signs", "Vital Signs");
                            rv.Category.Add(cc);
                            rv.Code = new Hl7.Fhir.Model.CodeableConcept("http://loinc.org", "29463-7", "Body Weight");
                            rv.Code.Coding.Add(new Hl7.Fhir.Model.Coding("http://snomed.info/sct", "27113001", "Body Weight"));
                            rv.Subject   = new Hl7.Fhir.Model.ResourceReference("patient/" + patid);
                            rv.Effective = Hl7.Fhir.Model.FhirDateTime.Now();
                            rv.Value     = new Hl7.Fhir.Model.Quantity(weight, "lbs");
                            ((Hl7.Fhir.Model.Quantity)rv.Value).Code = "[lb_av]";
                            var rslt = client.SaveResource(rv);
                            if (rslt)
                            {
                                string weightmsg = "";
                                string parm      = $"patient={patid}";
                                var    bundle    = (Hl7.Fhir.Model.Bundle)client.LoadResource("Observation", parm);
                                List <Hl7.Fhir.Model.Observation> weights = new List <Hl7.Fhir.Model.Observation>();
                                foreach (Hl7.Fhir.Model.Bundle.EntryComponent entry in bundle.Entry)
                                {
                                    Hl7.Fhir.Model.Observation o = (Hl7.Fhir.Model.Observation)entry.Resource;
                                    if (FHIRUtils.isCodeMatch(o.Code.Coding, "http://loinc.org", "29463-7"))
                                    {
                                        weights.Add(o);
                                    }
                                }
                                if (weights.Count > 1)
                                {
                                    Hl7.Fhir.Model.Observation[] sorted = weights.OrderBy(o => Convert.ToDateTime(o.Effective.ToString())).ToArray();
                                    decimal prevw = ((Hl7.Fhir.Model.SimpleQuantity)sorted[sorted.Length - 2].Value).Value.Value;
                                    decimal curw  = ((Hl7.Fhir.Model.SimpleQuantity)sorted[sorted.Length - 1].Value).Value.Value;
                                    decimal dif   = prevw - curw;
                                    if (dif < 0)
                                    {
                                        weightmsg = "Looks like you gained around " + Math.Round(Math.Abs(dif), 1) + " lbs.";
                                    }
                                    else if (dif > 0)
                                    {
                                        weightmsg = "Looks like you loss around " + Math.Round(Math.Abs(dif), 1) + " lbs. Keep it up!!";
                                    }
                                    else
                                    {
                                        weightmsg = "Your weight is holding steady";
                                    }
                                }
                                await context.PostAsync($"Thanks, I recorded your weight of {weight} lbs in your medical record\n\n{weightmsg}");
                            }
                            else
                            {
                                await context.PostAsync($"Sorry I had a problem posting your weight...try again later.");
                            }
                        }
                    }
                    else if (intent.intent == "ChartGlucose")
                    {
                        var entity = luisresp.FindEntityByType("builtin.number");
                        if (entity != null)
                        {
                            var glucose = Convert.ToDecimal(new String(entity.entity.Where(Char.IsDigit).ToArray()));
                            var unit    = "mg/dL";
                            Hl7.Fhir.Model.CodeableConcept loinc = new Hl7.Fhir.Model.CodeableConcept("http://loinc.org", "2345-7", "Glucose [Mass/​volume] in Serum or Plasma");
                            //convert mg/DL if mmol/l
                            if (glucose < 20)
                            {
                                glucose = glucose * 18;
                            }
                            Hl7.Fhir.Model.Observation rv = new Hl7.Fhir.Model.Observation();
                            rv.Status   = Hl7.Fhir.Model.ObservationStatus.Final;
                            rv.Category = new List <Hl7.Fhir.Model.CodeableConcept>();
                            Hl7.Fhir.Model.CodeableConcept cc = new Hl7.Fhir.Model.CodeableConcept("http://hl7.org/fhir/observation-category", "laboratory", "Laboratory");
                            rv.Category.Add(cc);
                            rv.Code           = loinc;
                            rv.Subject        = new Hl7.Fhir.Model.ResourceReference("patient/" + patid);
                            rv.Effective      = Hl7.Fhir.Model.FhirDateTime.Now();
                            rv.Issued         = DateTimeOffset.UtcNow;
                            rv.ReferenceRange = new List <Hl7.Fhir.Model.Observation.ReferenceRangeComponent>();
                            Hl7.Fhir.Model.Observation.ReferenceRangeComponent rrc = new Hl7.Fhir.Model.Observation.ReferenceRangeComponent();
                            rrc.High        = new Hl7.Fhir.Model.SimpleQuantity();
                            rrc.High.Unit   = "mg/dL";
                            rrc.High.Code   = rrc.High.Unit;
                            rrc.High.System = "http://unitsofmeasure.org";
                            rrc.High.Value  = 140;
                            rrc.Low         = new Hl7.Fhir.Model.SimpleQuantity();
                            rrc.Low.Unit    = "mg/dL";
                            rrc.Low.Code    = rrc.Low.Unit;
                            rrc.Low.System  = "http://unitsofmeasure.org";
                            rrc.Low.Value   = 70;
                            rv.ReferenceRange.Add(rrc);
                            rv.Value = new Hl7.Fhir.Model.Quantity(glucose, unit);
                            ((Hl7.Fhir.Model.Quantity)rv.Value).Code = unit;
                            var rslt = client.SaveResource(rv);
                            if (rslt)
                            {
                                int     numglucose = 0;
                                string  parm       = $"patient={patid}";
                                var     bundle     = (Hl7.Fhir.Model.Bundle)client.LoadResource("Observation", parm);
                                decimal bga        = 0;
                                foreach (Hl7.Fhir.Model.Bundle.EntryComponent entry in bundle.Entry)
                                {
                                    Hl7.Fhir.Model.Observation o = (Hl7.Fhir.Model.Observation)entry.Resource;
                                    if (FHIRUtils.isCodeMatch(o.Code.Coding, "http://loinc.org", "2345-7"))
                                    {
                                        bga = bga + ((Hl7.Fhir.Model.SimpleQuantity)o.Value).Value.Value;
                                        numglucose++;
                                    }
                                }
                                bga = Math.Round(bga / numglucose, 1);
                                decimal a1c   = ((Convert.ToDecimal(46.7) + bga) / Convert.ToDecimal(28.7));
                                string  bgmsg = $"Your blood glucose is averaging {bga}  mg/dL " + (bga > 140 ? "looks like it's running high" : (bga < 70 ? "looks like it's running low" : ""));
                                bgmsg = bgmsg + "\n\nYour estimated A1C is " + Convert.ToString(Math.Round(a1c, 1));

                                await context.PostAsync($"Thanks, I recorded your blood glucose of {glucose} mg/dL in your medical record\n\n{bgmsg}");
                            }
                            else
                            {
                                await context.PostAsync($"Sorry I had a problem posting your blood glucose...you can try again later.");
                            }
                        }
                        else
                        {
                            await context.PostAsync($"Sorry, I couldnt determine your blood glucose value...try again");
                        }
                    }
                    else if (intent.intent == "DisplayGlucose")
                    {
                        int      numglucose = 0;
                        string   parm       = $"patient={patid}";
                        var      bundle     = (Hl7.Fhir.Model.Bundle)client.LoadResource("Observation", parm);
                        decimal  bga        = 0;
                        decimal  la1c       = 0;
                        decimal  ea1c       = 0;
                        DateTime?dta1c      = null;
                        foreach (Hl7.Fhir.Model.Bundle.EntryComponent entry in bundle.Entry)
                        {
                            Hl7.Fhir.Model.Observation o = (Hl7.Fhir.Model.Observation)entry.Resource;
                            if (FHIRUtils.isCodeMatch(o.Code.Coding, "http://loinc.org", "2345-7"))
                            {
                                bga = bga + ((Hl7.Fhir.Model.SimpleQuantity)o.Value).Value.Value;
                                numglucose++;
                            }
                            else if (FHIRUtils.isCodeMatch(o.Code.Coding, "http://loinc.org", "4548-4"))
                            {
                                la1c  = ((Hl7.Fhir.Model.SimpleQuantity)o.Value).Value.Value;
                                dta1c = Convert.ToDateTime(o.Effective.ToString());
                            }
                        }
                        if (numglucose > 0)
                        {
                            bga  = Math.Round(bga / numglucose, 1);
                            ea1c = ((Convert.ToDecimal(46.7) + bga) / Convert.ToDecimal(28.7));
                        }
                        string a1cmsg = "I don't see any A1C tests on file for you.";
                        string bgmsg  = "I don't see any blood glucose tests on file for you.";
                        if (la1c > 0)
                        {
                            a1cmsg = $"Your last A1C test was on " + String.Format("{0:MM/dd/yyyy}", dta1c.Value) + " the result was " + Convert.ToString(la1c) + "% " + (la1c > 6 ? "thats high" : "");
                        }
                        if (bga > 0)
                        {
                            bgmsg = $"Your blood glucose is averaging {bga}  mg/dL " + (bga > 140 ? "looks like it's running high" : (bga < 70 ? "looks like it's running low" : ""));
                            bgmsg = bgmsg + "\n\nYour current estimated A1C is " + Convert.ToString(Math.Round(ea1c, 1)) + (ea1c < 6 ? " great control!" : (ea1c <= 7 ? " doing good for a diabetic!" : " need to work at lowering!"));
                        }
                        await context.PostAsync($"{a1cmsg}\n\n{bgmsg}");
                    }
                    else if (intent.intent == "DisplayCareplan")
                    {
                        //Call FHIR Server
                        string parm   = $"patient={patid}";
                        var    bundle = (Hl7.Fhir.Model.Bundle)client.LoadResource("CarePlan", parm);
                        if (bundle.Entry.Count == 0)
                        {
                            await context.PostAsync($"Sorry, I couldn't find a plan of care for you in the database...");
                        }
                        else
                        {
                            StringBuilder sb = new StringBuilder();
                            sb.Append("Your current plan of care addresses the following conditions:\n\n");
                            Hl7.Fhir.Model.CarePlan cp = (Hl7.Fhir.Model.CarePlan)bundle.Entry[0].Resource;
                            int x = 1;
                            foreach (var cond in cp.Addresses)
                            {
                                sb.Append(x++ + ". " + cond.Display + "\n\n");
                            }
                            sb.Append("\n\nYou have the following goals:\n\n");
                            x = 1;
                            foreach (var goal in cp.Goal)
                            {
                                sb.Append(x++ + ". " + goal.Display + "\n\n");
                            }
                            sb.Append("\n\nYou should:\n\n");
                            x = 1;
                            foreach (var act in cp.Activity)
                            {
                                if (act.Detail != null)
                                {
                                    sb.Append(x++ + ". " + act.Detail.Description + "\n\n");
                                }
                                else
                                {
                                    if (act.Reference != null && act.Reference.Reference.StartsWith("MedicationRequest"))
                                    {
                                        sb.Append(x++ + ". Take " + act.Reference.Display + " as directed.\n\n");
                                    }
                                }
                            }
                            await context.PostAsync(sb.ToString());
                        }
                    }
                    else
                    {
                        await context.PostAsync($"Sorry, I didn't understand {activity.Text}...");
                    }
                }
                context.Wait(MessageReceivedAsync);
            }
        }