FHIR Chat · Verständnis Problem, Kommunikation zwischen Client & Server · german (d-a-ch)

Stream: german (d-a-ch)

Topic: Verständnis Problem, Kommunikation zwischen Client & Server


view this post on Zulip Morris Miltz (Jul 05 2021 at 19:15):

Hallo zusammen,
ich steh gerade etwas auf dem Schlauch.
Ich möchte einen Patienten mit einigen Observations an den Server geben.
Die Observations haben eine Referenz auf den Patienten.
Ich erstelle ein Bundle für die Transaktion und gebe es an den Server.
Wenn ich nun den Patienten suche, finde ich diesen auch, aber nichts von den Observations.

Muss ich dem Patienten auch eine Referenz auf die Observations geben? (Wenn ja, wie geht das wenn ich mehrere Observations habe?)

Ich glaube ich hab hier ein Verständnis Problem.

Mein Ziel wäre es clientseitig über z. B. die Patienten - Id, alle Observations abrufen zu können, geht das denn überhaupt?

Oder gibt es eine Möglichkeit eine Art Observation-Array zu erstellen, das ich nur einmal referenzier und somit beliebig viele Observations an einen Patienten übergeben kann und darüber auch abrufen?

Vielen Dank für eure Hilfe.

view this post on Zulip Alexander Zautke (Jul 05 2021 at 19:59):

Wäre es möglich das Transaction Bundle hier zu posten? Dann können wir gerne drüber gucken wo es klemmt. Eigentlich wollte der Server sowohl die Patienten-Ressource als auch die Observations innerhalb der Transaction speichern.

view this post on Zulip Alexander Zautke (Jul 05 2021 at 20:03):

Über das sogenannte Chaining lässt sich auch eine Suchabfrage aller Observations anhand der Id der Patienten-Ressource durchführen:

[base]/Observation?patient.id=1234

Diese Suchanfrage würde alle Observations zurückgeben, die über die Observation.subject Referenz auf einen Patienten zeigen mit der ID 1234.

view this post on Zulip Alexander Zautke (Jul 05 2021 at 20:03):

Siehe https://www.hl7.org/fhir/search.html#chaining

view this post on Zulip Morris Miltz (Jul 06 2021 at 08:43):

Hallo, natürlich die Code-Zeilen sehen wie folgt aus:

val bundle: org.hl7.fhir.r4.model.Bundle = org.hl7.fhir.r4.model.Bundle()
bundle.setType(org.hl7.fhir.r4.model.Bundle.BundleType.TRANSACTION)

//Patient zum Bundle hinzufügen
bundle.addEntry().setFullUrl(patientTest.idElement.value).setResource(patientTest)
.request.setUrl("PatientTest").setIfNoneExist("identifier=WunddokuHSKE|301180")
.setMethod(org.hl7.fhir.r4.model.Bundle.HTTPVerb.POST)

//Observation zum Bundle hinzufügen
bundle.addEntry().setResource(observation).getRequest().setUrl("Observation").setMethod(org.hl7.fhir.r4.model.Bundle.HTTPVerb.POST)

//weiter Observation zum Bundle hinzufügen
bundle.addEntry().setResource(testObservation).getRequest().setUrl("TestObservation").setMethod(org.hl7.fhir.r4.model.Bundle.HTTPVerb.POST)
bundle.addEntry().setResource(testObservation2).request.setUrl("TestObservation2").setMethod(org.hl7.fhir.r4.model.Bundle.HTTPVerb.POST)

Oder meinten Sie den Inhalt des Bundle nach einem parsen /prettyprint?

Schon mal vielen Dank Ihnen

view this post on Zulip Yannick Börner (Jul 06 2021 at 10:29):

Gerne nach der Serialisierung als JSON/XML hier posten! Dann können andere Leser das Szenario einfach nachstellen und testen :-)

view this post on Zulip Morris Miltz (Jul 06 2021 at 11:23):

Okay, das ist die Aussgabe dazu mit JSON (prettyprint):

{
"resourceType": "Bundle",
"type": "transaction",
"entry": [ {
"fullUrl": "urn:uuid:f13e06af-f1a1-4e81-8c64-2f838df5035d",
"resource": {
"resourceType": "Patient",
"identifier": [ {
"system": "Wunddoku",
"value": "301180"
} ],
"name": [ {
"family": "Schütz",
"given": [ "dbuar", "Klaus" ]
} ],
"gender": "male",
"address": [ {
"city": "K-Town",
"state": "Bayern",
"postalCode": "01234",
"country": "Germany"
} ]
},
"request": {
"method": "POST",
"url": "PatientTest",
"ifNoneExist": "identifier=Wunddoku|301180"
}
}, {
"resource": {
"resourceType": "Observation",
"status": "final",
"code": {
"coding": [ {
"system": "test-??",
"code": "888888",
"display": "das gehört zu ... [#/volume]"
} ]
},
"subject": {
"reference": "urn:uuid:f13e06af-f1a1-4e81-8c64-2f838df5035d"
},
"valueQuantity": {
"value": 4.12,
"unit": "10 trillion/L",
"system": "wieder eine setSystem URL - Test",
"code": "10*12/L"
}
},
"request": {
"method": "POST",
I/System.out: "url": "Observation"
}
}, {
"resource": {
"resourceType": "Observation",
"status": "final",
"code": {
"coding": [ {
"system": "http://snomed.info/sct",
"code": "420226006"
} ]
},
"subject": {
"reference": "urn:uuid:f13e06af-f1a1-4e81-8c64-2f838df5035d"
},
"valueQuantity": {
"value": 88.0,
"system": "http://unitsofmeasure.org",
"code": "kg"
},
"referenceRange": [ {
"low": {
"value": 45,
"system": "http://unitsofmeasure.org",
"code": "kg"
},
"high": {
"value": 90,
"system": "http://unitsofmeasure.org",
"code": "kg"
}
} ]
},
"request": {
"method": "POST",
"url": "TestObservation"
}
}, {
"resource": {
"resourceType": "Observation",
"status": "final",
"code": {
"coding": [ {
"system": "http://test.code",
"code": "TestCode"
} ]
},
"subject": {
"reference": "urn:uuid:f13e06af-f1a1-4e81-8c64-2f838df5035d"
},
"valueString": "TestObservation2!!!!"
},
"request": {
"method": "POST",
"url": "TestObservation2"
}
} ]
}

Das ist die Ausgabe, wenn ich nur den Patienten ausgebe:

{
"resourceType": "Patient",
"identifier": [ {
"system": "Wunddoku",
"value": "301180"
} ],
"name": [ {
"family": "Schütz",
"given": [ "dbuar", "Klaus" ]
} ],
"gender": "male",
"address": [ {
"city": "K-Town",
"state": "Bayern",
"postalCode": "01234",
"country": "Germany"
} ]
}

view this post on Zulip Morris Miltz (Jul 06 2021 at 11:29):

Alexander Zautke said:

Über das sogenannte Chaining lässt sich auch eine Suchabfrage aller Observations anhand der Id der Patienten-Ressource durchführen:

[base]/Observation?patient.id=1234

Diese Suchanfrage würde alle Observations zurückgeben, die über die Observation.subject Referenz auf einen Patienten zeigen mit der ID 1234.

Hab das gerade ausprobiert, hat super funktioniert, habe dazu RESTClient als Firefox Addon verwendet. Dakeschön

view this post on Zulip Morris Miltz (Jul 06 2021 at 12:25):

Ich habe nun soweit ein paar Punkte getestet und es scheint zu funktionieren, auch die Observations habe ich finden können über den Patienten.

Was mir dennoch unklar ist, ich habe zwar in der Dokumentation die Ressourcen Group, List und Composition gefunden, bin mir aber nicht sicher ob ich diese dann richtig verwende.

Wie kurz angesprochen möchte ich einem Patienten einige Observations mitgeben, z. B. Wundfarbe, Wundexsudat, länge der Wunde, breite der Wunde usw.. dazu würde ich eine Observation wie folgt nutzten:

//Observation erstellen
testObservation.valueStringType.setValue("TestObservation!!!")
testObservation.setStatus(Observation.ObservationStatus.FINAL)
var coding : Coding = testObservation.code.addCoding()
coding.setCode("420226006").setSystem("http://snomed.info/sct")

//Referenz zum Patienten erstellen
testObservation.setSubject(Reference(patientTest.getIdElement().value))

//Observation an Bundle geben
bundle.addEntry().setResource(testObservation).getRequest().setUrl("TestObservation")
.setMethod(org.hl7.fhir.r4.model.Bundle.HTTPVerb.POST)

Sollte ich hier nun dies so für alle Observations machen (es könnten schon bis zu 30 sein), oder gibt es hierfür eine andere Ressource?
Übersehe ich etwas?

Danke für Ihre Hilfe

view this post on Zulip Stefan Lang (Jul 06 2021 at 15:30):

Wo kommen diese Endpunkte her? z.B.:

"request": {
"method": "POST",
"url": "PatientTest",
 ...
}

oder

"request": {
"method": "POST",
"url": "TestObservation"
}

Endpunkt für einen bestimmten Ressourcentyp ist immer [base]/[Name des Ressourcentyps], vgl. Abschnitt 3.1.0.1.2 Service Base URL unter http://www.hl7.org/fhir/http.html#general oder das Transaction-Bundle-Beispiel: http://www.hl7.org/fhir/bundle-transaction.xml.html

Ist das ein selbst implementierter Server?

view this post on Zulip Morris Miltz (Jul 06 2021 at 15:58):

Ich nutze zum testen den R4, kein selbst implementierter Server.
Die Übermittlung der Daten erfolgt über die Android App die gerade programmiere, welche Kotlin als Sprache verwendet.

Okay, ich werde mir Ihre links nochmal anschauen, Danke.

Die Werte werden aufgrund der im obigen Post erwähnten Codezeilen erstellt.

//Observation erstellen
testObservation.valueStringType.setValue("TestObservation!!!") <-- Hier
testObservation.setStatus(Observation.ObservationStatus.FINAL)
var coding : Coding = testObservation.code.addCoding()
coding.setCode("420226006").setSystem("http://snomed.info/sct")

//Observation an Bundle geben
bundle.addEntry().setResource(testObservation).getRequest().setUrl("TestObservation") <-- und hier
.setMethod(org.hl7.fhir.r4.model.Bundle.HTTPVerb.POST)

Wie gesagt, nur Beispielwerte um zunächst das Konzept zu testen.

view this post on Zulip Abel Stolz (Jul 12 2021 at 05:57):

Was ist denn "der R4"? R4 bezeichnet die 4. Version von FHIR (davor kamen STU3 und DSTU2). FHIR-Server sind z. B. HAPI oder Firely.

Man kann nicht einfach so einen eigenen Ressourcentyp "TestObservation" erstellen. Der Ressourcentyp muss in jedem Fall "Observation" sein. Man kann dann einfach die Ressource mit den Testdaten befüllen, oder z. B. zur Nachverfolgbarkeit meta.tag = "TestObservation" setzen.

view this post on Zulip Morris Miltz (Jul 16 2021 at 16:06):

Abel Stolz said:

Was ist denn "der R4"? R4 bezeichnet die 4. Version von FHIR (davor kamen STU3 und DSTU2). FHIR-Server sind z. B. HAPI oder Firely.

Man kann nicht einfach so einen eigenen Ressourcentyp "TestObservation" erstellen. Der Ressourcentyp muss in jedem Fall "Observation" sein. Man kann dann einfach die Ressource mit den Testdaten befüllen, oder z. B. zur Nachverfolgbarkeit meta.tag = "TestObservation" setzen.

Verzeihung dies war mir nicht bewusst. Ich meinte natürlich den HAPI TestServer mit der Base: http://hapi.fhir.org/baseR4.

Ich lege z. B. eine Observation wie folgt an:

private lateinit var wundexsudatObservation : Observation

  //Observation Wundexsudat
    wundexsudatObservation = Observation()
    wundexsudatObservation.setSubject(Reference(patientTEST1.getIdElement().value))
    wundexsudatObservation.valueStringType.value = "Wundexsudat Menge"
    wundexsudatObservation.status = Observation.ObservationStatus.FINAL
    var wundexsudatCoding : Coding = wundexsudatObservation.code.addCoding()
    when(pWundexsudat != "Bitte auswählen!"){
        wundexsudat_sp.selectedItemPosition == 1 -> {
            wundexsudatCoding.setCode("260413007").setSystem("http://snomed.info/sct")
        }
        wundexsudat_sp.selectedItemPosition == 2 -> {
            wundexsudatCoding.setCode("255507004").setSystem("http://snomed.info/sct")
        }
        wundexsudat_sp.selectedItemPosition == 3 -> {
            wundexsudatCoding.setCode("255508009").setSystem("http://snomed.info/sct")
        }
        wundexsudat_sp.selectedItemPosition == 4 -> {
            wundexsudatCoding.setCode("kein Code hierfür aber soltle moderat sein").setSystem("snomed hat nur 4 Stufen")
        }
        wundexsudat_sp.selectedItemPosition == 5 -> {
            wundexsudatCoding.setCode("255509001").setSystem("http://snomed.info/sct")
        }
    }

Und das ausgegebene Ergebnis sieht dann so aus:

"resource": {
"resourceType": "Observation",
"status": "final",
"code": {
"coding": [ {
"system": "http://snomed.info/sct",
"code": "255508009"
} ]
},
"valueString": "Wundexsudat Menge"
}

Ist das nicht korrekt?
(Ich möchte aktuell nicht nach irgend welchen Standards validieren oder ähnliches, die App, die diesen Code erzeugt, ist nur für Testzwecke um eine Kommunikation mit dem Server zu testen)

view this post on Zulip Abel Stolz (Jul 19 2021 at 05:52):

Nach dem Simplifier-Validator ist das korrekt (Standard R4.0.1), nach visueller Kontrolle und Abgleich mit http://hl7.org/fhir/observation.html auch. Das Problem ist: Man kann nicht wirklich sagen, ob die Ressource korrekt ist, wenn man sie nicht nach irgendeinem Standard misst. Ich habe also Core R4.0.1 genommen. Wenn es nur um die Kommunikation mit dem Server geht, dann verstehe ich nicht, wieso sich die Frage nach der Korrektheit überhaupt stellt. Man könnte ja eine inkorrekte Ressource schicken; wenn der Server eine Fehlermeldung schickt, dass die Ressource nicht korrekt ist, hat die Kommunikation funktioniert...

view this post on Zulip Mareike Przysucha (Jul 19 2021 at 07:59):

Hallo @Morris Miltz,
ich habe gerade das Gefühl, dass Code und Value durcheinander geraten sind.
codesagt, um was es sich handelt. Dort müsste stehen, dass es sich um die Menge an Wundexsudat handelt, z.B. mittels des SNOMED CT Codes (441281002) oder LOINC (39116-9).
Die Menge, im genannten Beispiel "medium" (SNOMED-Code 255508009), kommt dann in den value als valueCodeableConcept.
Daher würde ich die Frage: "Ist das nicht richtig?" mit "Stimmt, das ist nicht richtig" beantworten.

Ich habe einmal das Beispiel angepasst, wobei ich im Code sowohl den LOINC- als auch den SNOMED Code hinterlegt habe.

"resource": {
   "resourceType": "Observation",
   "status": "final",
   "code": {
      "coding": [
         {
            "system": "http://snomed.info/sct",
            "code": "441281002",
            "display": "Amount of exudate"
         } ,
         {
            "system": "http://loinc.org",
            "code": "39116-9",
            "display": "Drainage amount of Wound"
         }
      ]
   },
   "valueCodeableConcept": {
      "coding": [
         {
            "system": "http://snomed.info/sct",
            "code": "255508009",
            "display": "medium"
         }
      ]
   }
}

Ich hoffe, die Antwort hilft weiter.
Viele Grüße

view this post on Zulip Morris Miltz (Jul 19 2021 at 08:18):

Hallo @Mareike Przysucha vielen Dank für die Antwort.
Habe ich es dann richtig verstanden, dass der innerhalb vom code eben das coding wie snomed und loinc stehen, die dann Angeben was der Code sein soll. Also sozusagen der Überbegriff. Und im valueCodableConcept ich dann Einträge oder "arten" habe, die unter den "Überbegriff" fallen?

Bezug auf das obere Beispiel, hier hätte ich für das coding den snomed 441...
Und im valueCodableConcept dann denn 255.. mit medium, ist das dann so dass ich mehrere valueCodableConept erstellen kann. Also für z. B. high und low auch?

Vielen Dank nochmal :)

view this post on Zulip Mareike Przysucha (Jul 19 2021 at 08:28):

Gerne. Du kannst auch im value mehrere codings haben, jedoch sollten diese das gleiche repräsentieren. Wenn Du "high" und "low" einsetzt, sagst Du, dass bei Wunde XY sowohl viel als auch wenig Exsudat zur gleichen Zeit auftritt. Und das klappt nicht so richtig... Also solltest Du Dich dann auf eines konzentrieren.


Last updated: Apr 12 2022 at 19:14 UTC